From 9a1a5397697bdbbccf11b5ef0d90857637433881 Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Fri, 2 Jul 2021 00:23:04 -0400 Subject: [PATCH 01/10] tests: Add an initial docs parsing script --- scripts/public-traits-tests-generator.py | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100755 scripts/public-traits-tests-generator.py diff --git a/scripts/public-traits-tests-generator.py b/scripts/public-traits-tests-generator.py new file mode 100755 index 0000000000..e5799cb5ee --- /dev/null +++ b/scripts/public-traits-tests-generator.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +from subprocess import run +import json +import os + +doc_gen_cmd = ["cargo", "rustdoc", "--", "-Z", "unstable-options", "--output-format", "json"] +def main (): + doc_gen_result = run(doc_gen_cmd) + if doc_gen_result.returncode != 0: + print("Unable to generate the docs for the regex") + exit(1) + + with open(os.path.join("..", "target", "doc", "regex.json")) as docs_file: + docs = json.load(docs_file) + + from pprint import pprint + + index = docs['index'] + for key in index.keys(): + if index[key]['kind'] in ['enum', 'struct']: + pprint(index[key]) + + + + + + +if __name__ == "__main__": + main() + From c16ea177b9457792a9215d9f412d0d3473df697a Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Sat, 3 Jul 2021 15:02:16 -0400 Subject: [PATCH 02/10] lint: Make a url an autolink --- src/dfa.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dfa.rs b/src/dfa.rs index 4aee8039c6..27e610a2ac 100644 --- a/src/dfa.rs +++ b/src/dfa.rs @@ -31,7 +31,7 @@ considerably more complex than one might expect out of a DFA. A number of tricks are employed to make it fast. Tread carefully. N.B. While this implementation is heavily commented, Russ Cox's series of -articles on regexes is strongly recommended: https://swtch.com/~rsc/regexp/ +articles on regexes is strongly recommended: (As is the DFA implementation in RE2, which heavily influenced this implementation.) */ From 291fc67365105bb44f083c849f8b2f1273555272 Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Sat, 3 Jul 2021 18:22:29 -0400 Subject: [PATCH 03/10] feat: Improve the tests gen script --- scripts/public-traits-tests-generator.py | 31 ---------- scripts/public-traits-tests.py | 72 ++++++++++++++++++++++++ tests/marker_traits.rs | 46 +++++++++++++++ tests/test_default.rs | 49 +--------------- 4 files changed, 119 insertions(+), 79 deletions(-) delete mode 100755 scripts/public-traits-tests-generator.py create mode 100755 scripts/public-traits-tests.py create mode 100644 tests/marker_traits.rs diff --git a/scripts/public-traits-tests-generator.py b/scripts/public-traits-tests-generator.py deleted file mode 100755 index e5799cb5ee..0000000000 --- a/scripts/public-traits-tests-generator.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 - -from subprocess import run -import json -import os - -doc_gen_cmd = ["cargo", "rustdoc", "--", "-Z", "unstable-options", "--output-format", "json"] -def main (): - doc_gen_result = run(doc_gen_cmd) - if doc_gen_result.returncode != 0: - print("Unable to generate the docs for the regex") - exit(1) - - with open(os.path.join("..", "target", "doc", "regex.json")) as docs_file: - docs = json.load(docs_file) - - from pprint import pprint - - index = docs['index'] - for key in index.keys(): - if index[key]['kind'] in ['enum', 'struct']: - pprint(index[key]) - - - - - - -if __name__ == "__main__": - main() - diff --git a/scripts/public-traits-tests.py b/scripts/public-traits-tests.py new file mode 100755 index 0000000000..e1f11dc45d --- /dev/null +++ b/scripts/public-traits-tests.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 + +from subprocess import run +import datetime +import json +import os +from pprint import pprint + +PREAMBLE = ''' +// DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' +// on {date}. +'''.lstrip() + +CMD = ["cargo", "rustdoc", "-q", "--", "-Z", "unstable-options", "--output-format", "json"] + +def get_public_of_kind(kinds, elements, index): + keys_of_kind = filter(lambda key: index[key]['kind'] in kinds, elements) + public_of_kind = filter(lambda key: index[key]['visibility'] == 'public', keys_of_kind) + return map(lambda key: index[key], public_of_kind) + +def gen_test(path): + return f"assert_marker_traits::<{path}>();" + +def gen_tests(): + doc_gen_result = run(CMD) + if doc_gen_result.returncode != 0: + print("Unable to generate the docs for the regex") + exit(1) + + with open(os.path.join("target", "doc", "regex.json")) as docs_file: + docs = json.load(docs_file) + index = docs['index'] + + tests = [] + public_modules = get_public_of_kind(['module'], index.keys(), index) + for mod in public_modules: + tests.append('') + types = get_public_of_kind(['struct'], mod['inner']['items'], index) + for type in types: + # if mod['name'] == 'regex' and type['name'] == 'CaptureMatches': + # for key in type['inner']['impls']: + # # for impl in index[key]: + # pprint(index[key]) + + + prefix = '' if mod['inner']['is_crate'] else 'regex::' + test = gen_test(f"{prefix}{mod['name']}::{type['name']}") + tests.append(test) + + return tests + + + + +def get_assert_definition(): + return "\tfn assert_marker_traits() {}\n" + +def main(): + with open(os.path.join("tests", "marker_traits.rs"), 'w') as f: + f.write(PREAMBLE.format(date=str(datetime.datetime.now()))) + f.write('\n') + f.write("#[test]\nfn marker_traits() {\n") + f.write("\tuse std::panic::{RefUnwindSafe, UnwindSafe};\n") + f.write(get_assert_definition()) + for test in gen_tests(): + f.write(f"\t{test}\n") + f.write("}\n") + + +if __name__ == '__main__': + main() + diff --git a/tests/marker_traits.rs b/tests/marker_traits.rs new file mode 100644 index 0000000000..3a76acf5d1 --- /dev/null +++ b/tests/marker_traits.rs @@ -0,0 +1,46 @@ +// DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' +// on 2021-07-03 16:14:18.759956. + +#[test] +fn marker_traits() { + use std::panic::{RefUnwindSafe, UnwindSafe}; + fn assert_marker_traits() {} + + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + // assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + // assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + // assert_marker_traits::>(); + // assert_marker_traits::(); + // assert_marker_traits::(); + assert_marker_traits::(); + + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + // assert_marker_traits::(); + // assert_marker_traits::(); + // assert_marker_traits::(); + // assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + // assert_marker_traits::>(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); + assert_marker_traits::(); +} diff --git a/tests/test_default.rs b/tests/test_default.rs index d4365fbb34..454ff56c61 100644 --- a/tests/test_default.rs +++ b/tests/test_default.rs @@ -44,6 +44,7 @@ mod api_str; mod crazy; mod flags; mod fowler; +mod marker_traits; mod misc; mod multiline; mod noparse; @@ -79,54 +80,6 @@ fn allow_octal() { assert!(regex::RegexBuilder::new(r"\0").octal(true).build().is_ok()); } -#[test] -fn oibits() { - use regex::bytes; - use regex::{Regex, RegexBuilder, RegexSet, RegexSetBuilder}; - use std::panic::{RefUnwindSafe, UnwindSafe}; - - fn assert_send() {} - fn assert_sync() {} - fn assert_unwind_safe() {} - fn assert_ref_unwind_safe() {} - - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); - - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); - - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); - - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); - assert_send::(); - assert_sync::(); - assert_unwind_safe::(); - assert_ref_unwind_safe::(); -} - // See: https://github.com/rust-lang/regex/issues/568 #[test] fn oibits_regression() { From 33b612d9faccfd469e91cb96ced23ce30269ab98 Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Sat, 3 Jul 2021 18:51:50 -0400 Subject: [PATCH 04/10] feat: Generated the oibit tests and hand-massaged them --- scripts/public-traits-tests.py | 72 ----------- scripts/public-types-tests.py | 93 ++++++++++++++ tests/marker_traits.rs | 216 +++++++++++++++++++++++++++------ 3 files changed, 269 insertions(+), 112 deletions(-) delete mode 100755 scripts/public-traits-tests.py create mode 100755 scripts/public-types-tests.py diff --git a/scripts/public-traits-tests.py b/scripts/public-traits-tests.py deleted file mode 100755 index e1f11dc45d..0000000000 --- a/scripts/public-traits-tests.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 - -from subprocess import run -import datetime -import json -import os -from pprint import pprint - -PREAMBLE = ''' -// DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' -// on {date}. -'''.lstrip() - -CMD = ["cargo", "rustdoc", "-q", "--", "-Z", "unstable-options", "--output-format", "json"] - -def get_public_of_kind(kinds, elements, index): - keys_of_kind = filter(lambda key: index[key]['kind'] in kinds, elements) - public_of_kind = filter(lambda key: index[key]['visibility'] == 'public', keys_of_kind) - return map(lambda key: index[key], public_of_kind) - -def gen_test(path): - return f"assert_marker_traits::<{path}>();" - -def gen_tests(): - doc_gen_result = run(CMD) - if doc_gen_result.returncode != 0: - print("Unable to generate the docs for the regex") - exit(1) - - with open(os.path.join("target", "doc", "regex.json")) as docs_file: - docs = json.load(docs_file) - index = docs['index'] - - tests = [] - public_modules = get_public_of_kind(['module'], index.keys(), index) - for mod in public_modules: - tests.append('') - types = get_public_of_kind(['struct'], mod['inner']['items'], index) - for type in types: - # if mod['name'] == 'regex' and type['name'] == 'CaptureMatches': - # for key in type['inner']['impls']: - # # for impl in index[key]: - # pprint(index[key]) - - - prefix = '' if mod['inner']['is_crate'] else 'regex::' - test = gen_test(f"{prefix}{mod['name']}::{type['name']}") - tests.append(test) - - return tests - - - - -def get_assert_definition(): - return "\tfn assert_marker_traits() {}\n" - -def main(): - with open(os.path.join("tests", "marker_traits.rs"), 'w') as f: - f.write(PREAMBLE.format(date=str(datetime.datetime.now()))) - f.write('\n') - f.write("#[test]\nfn marker_traits() {\n") - f.write("\tuse std::panic::{RefUnwindSafe, UnwindSafe};\n") - f.write(get_assert_definition()) - for test in gen_tests(): - f.write(f"\t{test}\n") - f.write("}\n") - - -if __name__ == '__main__': - main() - diff --git a/scripts/public-types-tests.py b/scripts/public-types-tests.py new file mode 100755 index 0000000000..0aaaf89133 --- /dev/null +++ b/scripts/public-types-tests.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 + +from subprocess import run +import datetime +import json +import os +from pprint import pprint + +PREAMBLE = """ +// DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' +// on {date}. +""".lstrip() + +CMD = [ + "cargo", + "rustdoc", + "-q", + "--", + "-Z", + "unstable-options", + "--output-format", + "json", +] + + +def get_public_of_kind(kinds, elements, index): + keys_of_kind = filter(lambda key: index[key]["kind"] in kinds, elements) + public_of_kind = filter( + lambda key: index[key]["visibility"] == "public", keys_of_kind + ) + return map(lambda key: index[key], public_of_kind) + + +def gen_test(path): + tests = [ + f"\tassert_send::<{path}>();", + f"\tassert_sync::<{path}>();", + f"\tassert_unwind_safe::<{path}>();", + f"\tassert_ref_unwind_safe::<{path}>();", + "" + ] + return "\n".join(tests) + + +def gen_tests(): + doc_gen_result = run(CMD) + if doc_gen_result.returncode != 0: + print("Unable to generate the docs for the regex") + exit(1) + + with open(os.path.join("target", "doc", "regex.json")) as docs_file: + docs = json.load(docs_file) + index = docs["index"] + + tests = [] + public_modules = get_public_of_kind(["module"], index.keys(), index) + for mod in public_modules: + tests.append("") + types = get_public_of_kind(["struct"], mod["inner"]["items"], index) + for type in types: + prefix = "" if mod["inner"]["is_crate"] else "regex::" + test = gen_test(f"{prefix}{mod['name']}::{type['name']}") + tests.append(test) + + return tests + + +def get_assert_definitions(): + definitions = [ + "\tfn assert_send() {}", + "\tfn assert_sync() {}", + "\tfn assert_unwind_safe() {}", + "\tfn assert_ref_unwind_safe() {}", + ] + return "\n".join(definitions) + + +def main(): + with open(os.path.join("tests", "marker_traits.rs"), "w") as f: + f.write(PREAMBLE.format(date=str(datetime.datetime.now()))) + f.write("\n") + f.write("#[test]\nfn marker_traits() {\n") + f.write("\tuse std::panic::{RefUnwindSafe, UnwindSafe};\n") + f.write("\n") + f.write(get_assert_definitions()) + f.write("\n") + for test in gen_tests(): + f.write(f"{test}\n") + f.write("}\n") + + +if __name__ == "__main__": + main() diff --git a/tests/marker_traits.rs b/tests/marker_traits.rs index 3a76acf5d1..5a58d49901 100644 --- a/tests/marker_traits.rs +++ b/tests/marker_traits.rs @@ -1,46 +1,182 @@ // DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' -// on 2021-07-03 16:14:18.759956. +// on 2021-07-03 18:47:26.528306. #[test] fn marker_traits() { use std::panic::{RefUnwindSafe, UnwindSafe}; - fn assert_marker_traits() {} - - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - // assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - // assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - // assert_marker_traits::>(); - // assert_marker_traits::(); - // assert_marker_traits::(); - assert_marker_traits::(); - - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - // assert_marker_traits::(); - // assert_marker_traits::(); - // assert_marker_traits::(); - // assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - // assert_marker_traits::>(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); - assert_marker_traits::(); + + fn assert_send() {} + fn assert_sync() {} + fn assert_unwind_safe() {} + fn assert_ref_unwind_safe() {} + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::>(); + assert_sync::>(); + assert_ref_unwind_safe::>(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::>(); + assert_sync::>(); + assert_ref_unwind_safe::>(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); } From 8ecad2b1b1b009255646703297efc38c8781ad9b Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Sat, 3 Jul 2021 18:52:17 -0400 Subject: [PATCH 05/10] lint: Remove unused import --- scripts/public-types-tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/public-types-tests.py b/scripts/public-types-tests.py index 0aaaf89133..0d59ea0699 100755 --- a/scripts/public-types-tests.py +++ b/scripts/public-types-tests.py @@ -4,7 +4,6 @@ import datetime import json import os -from pprint import pprint PREAMBLE = """ // DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' From 2285f848e7b3434341e7ef80956ea95abd37683a Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Sat, 3 Jul 2021 19:55:35 -0400 Subject: [PATCH 06/10] feat: Rework the script to accept a flag --- scripts/public-types-tests.py | 71 +++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/scripts/public-types-tests.py b/scripts/public-types-tests.py index 0d59ea0699..a1438af423 100755 --- a/scripts/public-types-tests.py +++ b/scripts/public-types-tests.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from subprocess import run +import argparse import datetime import json import os @@ -36,32 +37,44 @@ def gen_test(path): f"\tassert_sync::<{path}>();", f"\tassert_unwind_safe::<{path}>();", f"\tassert_ref_unwind_safe::<{path}>();", - "" + "", ] return "\n".join(tests) -def gen_tests(): +def gen_docs(): doc_gen_result = run(CMD) if doc_gen_result.returncode != 0: print("Unable to generate the docs for the regex") exit(1) + +def get_public_types(): with open(os.path.join("target", "doc", "regex.json")) as docs_file: docs = json.load(docs_file) index = docs["index"] - tests = [] + type_paths = [] public_modules = get_public_of_kind(["module"], index.keys(), index) for mod in public_modules: - tests.append("") types = get_public_of_kind(["struct"], mod["inner"]["items"], index) for type in types: prefix = "" if mod["inner"]["is_crate"] else "regex::" - test = gen_test(f"{prefix}{mod['name']}::{type['name']}") - tests.append(test) + type_path = f"{prefix}{mod['name']}::{type['name']}" + type_paths.append(type_path) + + return type_paths - return tests + +def gen_tests(): + tests = [] + types = get_public_types() + for type in types: + tests.append("") + test = gen_test(type) + tests.append(test) + + return tests def get_assert_definitions(): @@ -74,7 +87,7 @@ def get_assert_definitions(): return "\n".join(definitions) -def main(): +def write_tests(): with open(os.path.join("tests", "marker_traits.rs"), "w") as f: f.write(PREAMBLE.format(date=str(datetime.datetime.now()))) f.write("\n") @@ -88,5 +101,47 @@ def main(): f.write("}\n") +def check_existence(): + types = get_public_types() + with open(os.path.join("tests", "marker_traits.rs")) as f: + lines = f.readlines() + for type in types: + if any(type in line for line in lines): + continue + else: + exit(1) + + exit(0) + + +def main(): + p = argparse.ArgumentParser( + "A script to manage marker-traits tests.", + description="Checks for the existence of tests for the public API types, " + "failing when there are missing tests for a marker trait of " + "a type.", + ) + p.add_argument( + "-g", + "--generate-tests", + action="store_true", + help=( + "If set, the script will generate a " + "tests/marker_traits.rs file containing a test that " + "checks the auto traits of the public API types " + "(These tests might need to be updated after generating them)." + ), + ) + + args = p.parse_args() + + gen_docs() + + if args.generate_tests: + write_tests() + else: + check_existence() + + if __name__ == "__main__": main() From fda6be0c88d2a1b523016416e74b32f37e2788b4 Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Fri, 9 Jul 2021 13:03:40 -0400 Subject: [PATCH 07/10] docs: Add explanatory comments and a success/failure message --- scripts/public-types-tests.py | 52 +++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/scripts/public-types-tests.py b/scripts/public-types-tests.py index a1438af423..c40bda2617 100755 --- a/scripts/public-types-tests.py +++ b/scripts/public-types-tests.py @@ -22,16 +22,36 @@ "json", ] +def gen_docs(): + """Runs the command to retrieve the docs of this crate. -def get_public_of_kind(kinds, elements, index): - keys_of_kind = filter(lambda key: index[key]["kind"] in kinds, elements) + If the command fails, the script exits. + """ + doc_gen_result = run(CMD) + if doc_gen_result.returncode != 0: + print("Unable to generate the docs for the regex") + exit(1) + + +def get_public_of_kind(kinds, elements, docs): + """Gets the items that are of some kind in the public API. + + `kinds` is a list of item kinds. Ex: ["module", "struct"] + `elements` are the keys in the docs json schema to search in. + `docs` is usually the slice of the json tree that we care about. + """ + keys_of_kind = filter(lambda key: docs[key]["kind"] in kinds, elements) public_of_kind = filter( - lambda key: index[key]["visibility"] == "public", keys_of_kind + lambda key: docs[key]["visibility"] == "public", keys_of_kind ) - return map(lambda key: index[key], public_of_kind) + return map(lambda key: docs[key], public_of_kind) def gen_test(path): + """Generates 4 valid lines of Rust code that assert marker traits on a type. + + `path` is a fully qualified type. Ex: regex::bytes::Regex + """ tests = [ f"\tassert_send::<{path}>();", f"\tassert_sync::<{path}>();", @@ -42,14 +62,13 @@ def gen_test(path): return "\n".join(tests) -def gen_docs(): - doc_gen_result = run(CMD) - if doc_gen_result.returncode != 0: - print("Unable to generate the docs for the regex") - exit(1) - - def get_public_types(): + """Reads the public types from the json dump of the docs of this crate. + + After generating the docs, this function is used to read the dump in + json format located at target/doc/regex.json. Then, it generates the + fully qualified paths for each type of the public API of the crate. + """ with open(os.path.join("target", "doc", "regex.json")) as docs_file: docs = json.load(docs_file) index = docs["index"] @@ -78,6 +97,8 @@ def gen_tests(): def get_assert_definitions(): + """Generates the definitions of the assert functions we use to test marker + traits.""" definitions = [ "\tfn assert_send() {}", "\tfn assert_sync() {}", @@ -88,6 +109,7 @@ def get_assert_definitions(): def write_tests(): + """Writes the generated tests to the tests/marker_traits.rs file.""" with open(os.path.join("tests", "marker_traits.rs"), "w") as f: f.write(PREAMBLE.format(date=str(datetime.datetime.now()))) f.write("\n") @@ -102,15 +124,21 @@ def write_tests(): def check_existence(): + """Fails the script when a type in the API doesn't have a corresponding marker trait test + in the tests/marker_traits.rs file.""" types = get_public_types() - with open(os.path.join("tests", "marker_traits.rs")) as f: + test_path = os.path.join("tests", "marker_traits.rs") + with open(test_path ) as f: lines = f.readlines() for type in types: if any(type in line for line in lines): continue else: + print("Failed check!\n") + print(f"A marker trait test for {type} was not found in {test_path}.") exit(1) + print("Success!\nThe existence check found that every type has a corresponding test.") exit(0) From 90105868886416cd80c56ea497d476e7cb8ca02f Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Fri, 9 Jul 2021 13:16:05 -0400 Subject: [PATCH 08/10] fix: Incorrect name of the script --- scripts/public-types-tests.py | 2 +- tests/marker_traits.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/public-types-tests.py b/scripts/public-types-tests.py index c40bda2617..436b99e66e 100755 --- a/scripts/public-types-tests.py +++ b/scripts/public-types-tests.py @@ -7,7 +7,7 @@ import os PREAMBLE = """ -// DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' +// DO NOT EDIT. Automatically generated by 'scripts/public-types-tests.py' // on {date}. """.lstrip() diff --git a/tests/marker_traits.rs b/tests/marker_traits.rs index 5a58d49901..4da11ad4cc 100644 --- a/tests/marker_traits.rs +++ b/tests/marker_traits.rs @@ -1,4 +1,4 @@ -// DO NOT EDIT. Automatically generated by 'scripts/public-traits-tests.py' +// DO NOT EDIT. Automatically generated by 'scripts/public-types-tests.py' // on 2021-07-03 18:47:26.528306. #[test] From 86bbff4f39e9e5c78bf0be35324df8946907a396 Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Sat, 7 Aug 2021 19:12:17 -0400 Subject: [PATCH 09/10] build: Hook up script in github actions --- .github/workflows/ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 659cfce653..d6552b1e6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -156,6 +156,13 @@ jobs: run: | cargo test --test default --no-default-features --features 'std pattern unicode-perl' + - if: matrix.build == 'nightly' + name: Run marker-traits tests + uses: actions/setup-python@v2 + with: + python-version: 3.8 + run: ./scripts/public-types-tests.py + rustfmt: name: rustfmt runs-on: ubuntu-18.04 From b685b3f600c6abc1dbe2a960b2b9c0bf51ab3a29 Mon Sep 17 00:00:00 2001 From: Alexander Gonzalez Date: Sat, 7 Aug 2021 19:53:58 -0400 Subject: [PATCH 10/10] build: Remove the 'uses' key in ci.yml --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6552b1e6f..808c097c58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -158,9 +158,6 @@ jobs: - if: matrix.build == 'nightly' name: Run marker-traits tests - uses: actions/setup-python@v2 - with: - python-version: 3.8 run: ./scripts/public-types-tests.py rustfmt: