From 7d4dd78679453010fc71aa51a51fbf4e13b018a8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 17 Sep 2023 16:17:30 -0400 Subject: [PATCH] Apply black to move Python style to standard form. --- make_dungeon.py | 250 +++++++++++++++++++++++--------------- make_graph.py | 52 +++++--- tests/coverage_dungeon.py | 114 ++++++++++------- 3 files changed, 265 insertions(+), 151 deletions(-) diff --git a/make_dungeon.py b/make_dungeon.py index bae97f2..12f39e7 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -24,6 +24,7 @@ DONOTEDIT_COMMENT = "/* Generated from adventure.yaml - do not hand-hack! */\n\n statedefines = "" + def make_c_string(string): """Render a Python string into C string literal format.""" if string is None: @@ -35,14 +36,16 @@ def make_c_string(string): string = '"' + string + '"' return string + def get_refs(l): reflist = [x[0] for x in l] ref_str = "" for ref in reflist: ref_str += " {},\n".format(ref) - ref_str = ref_str[:-1] # trim trailing newline + ref_str = ref_str[:-1] # trim trailing newline return ref_str + def get_string_group(strings): template = """{{ .strs = {}, @@ -51,20 +54,24 @@ def get_string_group(strings): if strings == []: strs = "NULL" else: - strs = "(const char* []) {" + ", ".join([make_c_string(s) for s in strings]) + "}" + strs = ( + "(const char* []) {" + ", ".join([make_c_string(s) for s in strings]) + "}" + ) n = len(strings) sg_str = template.format(strs, n) return sg_str + def get_arbitrary_messages(arb): template = """ {}, """ arb_str = "" for item in arb: arb_str += template.format(make_c_string(item[1])) - arb_str = arb_str[:-1] # trim trailing newline + arb_str = arb_str[:-1] # trim trailing newline return arb_str + def get_class_messages(cls): template = """ {{ .threshold = {}, @@ -76,9 +83,10 @@ def get_class_messages(cls): threshold = item["threshold"] message = make_c_string(item["message"]) cls_str += template.format(threshold, message) - cls_str = cls_str[:-1] # trim trailing newline + cls_str = cls_str[:-1] # trim trailing newline return cls_str + def get_turn_thresholds(trn): template = """ {{ .threshold = {}, @@ -92,9 +100,10 @@ def get_turn_thresholds(trn): point_loss = item["point_loss"] message = make_c_string(item["message"]) trn_str += template.format(threshold, point_loss, message) - trn_str = trn_str[:-1] # trim trailing newline + trn_str = trn_str[:-1] # trim trailing newline return trn_str + def get_locations(loc): template = """ {{ // {}: {} .description = {{ @@ -112,9 +121,10 @@ def get_locations(loc): sound = item[1].get("sound", "SILENT") loud = "true" if item[1].get("loud") else "false" loc_str += template.format(i, item[0], short_d, long_d, sound, loud) - loc_str = loc_str[:-1] # trim trailing newline + loc_str = loc_str[:-1] # trim trailing newline return loc_str + def get_objects(obj): template = """ {{ // {}: {} .words = {}, @@ -154,7 +164,7 @@ def get_objects(obj): descriptions_str += " " * 12 + make_c_string(l_msg) + ",\n" for label in attr.get("states", []): labels.append(label) - descriptions_str = descriptions_str[:-1] # trim trailing newline + descriptions_str = descriptions_str[:-1] # trim trailing newline if labels: global statedefines statedefines += "/* States for %s */\n" % item[0] @@ -168,21 +178,21 @@ def get_objects(obj): else: for l_msg in attr["sounds"]: sounds_str += " " * 12 + make_c_string(l_msg) + ",\n" - sounds_str = sounds_str[:-1] # trim trailing newline + sounds_str = sounds_str[:-1] # trim trailing newline texts_str = "" if attr.get("texts") is None: texts_str = " " * 12 + "NULL," else: for l_msg in attr["texts"]: texts_str += " " * 12 + make_c_string(l_msg) + ",\n" - texts_str = texts_str[:-1] # trim trailing newline + texts_str = texts_str[:-1] # trim trailing newline changes_str = "" if attr.get("changes") is None: changes_str = " " * 12 + "NULL," else: for l_msg in attr["changes"]: changes_str += " " * 12 + make_c_string(l_msg) + ",\n" - changes_str = changes_str[:-1] # trim trailing newline + changes_str = changes_str[:-1] # trim trailing newline locs = attr.get("locations", ["LOC_NOWHERE", "LOC_NOWHERE"]) immovable = attr.get("immovable", False) try: @@ -192,11 +202,24 @@ def get_objects(obj): sys.stderr.write("dungeon: unknown object location in %s\n" % locs) sys.exit(1) treasure = "true" if attr.get("treasure") else "false" - obj_str += template.format(i, item[0], words_str, i_msg, locs[0], locs[1], treasure, descriptions_str, sounds_str, texts_str, changes_str) - obj_str = obj_str[:-1] # trim trailing newline + obj_str += template.format( + i, + item[0], + words_str, + i_msg, + locs[0], + locs[1], + treasure, + descriptions_str, + sounds_str, + texts_str, + changes_str, + ) + obj_str = obj_str[:-1] # trim trailing newline statedefines += "/* Maximum state value */\n#define MAX_STATE %d\n" % max_state return obj_str + def get_obituaries(obit): template = """ {{ .query = {}, @@ -208,9 +231,10 @@ def get_obituaries(obit): query = make_c_string(o["query"]) yes = make_c_string(o["yes_response"]) obit_str += template.format(query, yes) - obit_str = obit_str[:-1] # trim trailing newline + obit_str = obit_str[:-1] # trim trailing newline return obit_str + def get_hints(hnt): template = """ {{ .number = {}, @@ -229,9 +253,10 @@ def get_hints(hnt): question = make_c_string(item["question"]) hint = make_c_string(item["hint"]) hnt_str += template.format(number, penalty, turns, question, hint) - hnt_str = hnt_str[:-1] # trim trailing newline + hnt_str = hnt_str[:-1] # trim trailing newline return hnt_str + def get_condbits(locations): cnd_str = "" for (name, loc) in locations: @@ -242,7 +267,7 @@ def get_condbits(locations): if conditions[flag]: flaglist.append(flag) line = "|".join([("(1<500 message N-500 from section 6 is printed, - # and he stays wherever he is. + # If N<=300 it is the location to go to. + # If 300500 message N-500 from section 6 is printed, + # and he stays wherever he is. # Meanwhile, M specifies the conditions on the motion. - # If M=0 it's unconditional. - # If 0 0: arc += ' [label="%s"]' % label print(" " + arc) diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index 2b4c515..e4ca88e 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -29,42 +29,45 @@ DEFAULT_HTML_OUTPUT_PATH = "../coverage/adventure.yaml.html" DANGLING_ACTIONS = ["ACT_VERSION"] DANGLING_MESSAGES = ["SAVERESUME_DISABLED"] -STDOUT_REPORT_CATEGORY = " {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n" +STDOUT_REPORT_CATEGORY = ( + " {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n" +) -HTML_SUMMARY_ROW = ''' +HTML_SUMMARY_ROW = """ {name}: {total} {covered} {percent:.1f}% -''' +""" -HTML_CATEGORY_SECTION = ''' +HTML_CATEGORY_SECTION = """ {rows}   -''' +""" -HTML_CATEGORY_HEADER = ''' +HTML_CATEGORY_HEADER = """ {label} {cells} -''' +""" HTML_CATEGORY_HEADER_CELL = '{}\n' HTML_CATEGORY_COVERAGE_CELL = ' \n' -HTML_CATEGORY_ROW = ''' +HTML_CATEGORY_ROW = """ {id} {cells} -''' +""" + def search(needle, haystack): # Search for needle in haystack, first escaping needle for regex, then @@ -75,16 +78,19 @@ def search(needle, haystack): # if needle is empty, assume we're going to find an empty string return True - needle_san = re.escape(needle) \ - .replace("\\n", "\n") \ - .replace("\\t", "\t") \ - .replace("%S", ".*") \ - .replace("%s", ".*") \ - .replace("%d", ".*") \ - .replace("%V", ".*") + needle_san = ( + re.escape(needle) + .replace("\\n", "\n") + .replace("\\t", "\t") + .replace("%S", ".*") + .replace("%s", ".*") + .replace("%d", ".*") + .replace("%V", ".*") + ) return re.search(needle_san, haystack) + def obj_coverage(objects, text, report): # objects have multiple descriptions based on state for _, objouter in enumerate(objects): @@ -93,19 +99,20 @@ def obj_coverage(objects, text, report): for j, desc in enumerate(obj["descriptions"]): name = "{}[{}]".format(obj_name, j) if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 if not report["messages"][name]["covered"] and search(desc, text): report["messages"][name]["covered"] = True report["covered"] += 1 + def loc_coverage(locations, text, report): # locations have a long and a short description, that each have to # be checked separately for name, loc in locations: desc = loc["description"] if name not in report["messages"]: - report["messages"][name] = {"long" : False, "short": False} + report["messages"][name] = {"long": False, "short": False} report["total"] += 2 if not report["messages"][name]["long"] and search(desc["long"], text): report["messages"][name]["long"] = True @@ -114,6 +121,7 @@ def loc_coverage(locations, text, report): report["messages"][name]["short"] = True report["covered"] += 1 + def hint_coverage(obituaries, text, report): # hints have a "question" where the hint is offered, followed # by the actual hint if the player requests it @@ -121,7 +129,7 @@ def hint_coverage(obituaries, text, report): hint = hintouter["hint"] name = hint["name"] if name not in report["messages"]: - report["messages"][name] = {"question" : False, "hint": False} + report["messages"][name] = {"question": False, "hint": False} report["total"] += 2 if not report["messages"][name]["question"] and search(hint["question"], text): report["messages"][name]["question"] = True @@ -130,50 +138,61 @@ def hint_coverage(obituaries, text, report): report["messages"][name]["hint"] = True report["covered"] += 1 + def obit_coverage(obituaries, text, report): # obituaries have a "query" where it asks the player for a resurrection, # followed by a snarky comment if the player says yes for name, obit in enumerate(obituaries): if name not in report["messages"]: - report["messages"][name] = {"query" : False, "yes_response": False} + report["messages"][name] = {"query": False, "yes_response": False} report["total"] += 2 if not report["messages"][name]["query"] and search(obit["query"], text): report["messages"][name]["query"] = True report["covered"] += 1 - if not report["messages"][name]["yes_response"] and search(obit["yes_response"], text): + if not report["messages"][name]["yes_response"] and search( + obit["yes_response"], text + ): report["messages"][name]["yes_response"] = True report["covered"] += 1 + def threshold_coverage(classes, text, report): # works for class thresholds and turn threshold, which have a "message" # property for name, item in enumerate(classes): if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 if not report["messages"][name]["covered"] and search(item["message"], text): report["messages"][name]["covered"] = True report["covered"] += 1 + def arb_coverage(arb_msgs, text, report): for name, message in arb_msgs: if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 - if not report["messages"][name]["covered"] and (search(message, text) or name in DANGLING_MESSAGES): + if not report["messages"][name]["covered"] and ( + search(message, text) or name in DANGLING_MESSAGES + ): report["messages"][name]["covered"] = True report["covered"] += 1 + def actions_coverage(items, text, report): # works for actions for name, item in items: if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 - if not report["messages"][name]["covered"] and (search(item["message"], text) or name in DANGLING_ACTIONS): + if not report["messages"][name]["covered"] and ( + search(item["message"], text) or name in DANGLING_ACTIONS + ): report["messages"][name]["covered"] = True report["covered"] += 1 + def coverage_report(db, check_file_contents): # Create report for each category, including total items, number of items # covered, and a list of the covered messages @@ -181,10 +200,10 @@ def coverage_report(db, check_file_contents): for name in db.keys(): # initialize each catagory report[name] = { - "name" : name, # convenience for string formatting - "total" : 0, - "covered" : 0, - "messages" : {} + "name": name, # convenience for string formatting + "total": 0, + "covered": 0, + "messages": {}, } # search for each message in every test check file @@ -200,20 +219,21 @@ def coverage_report(db, check_file_contents): return report + if __name__ == "__main__": # load DB try: - with open(YAML_PATH, "r", encoding='ascii', errors='surrogateescape') as f: + with open(YAML_PATH, "r", encoding="ascii", errors="surrogateescape") as f: db = yaml.safe_load(f) except IOError as e: - print('ERROR: could not load %s (%s)' % (YAML_PATH, e.strerror)) + print("ERROR: could not load %s (%s)" % (YAML_PATH, e.strerror)) sys.exit(-1) # get contents of all the check files check_file_contents = [] for filename in os.listdir(TEST_DIR): if filename.endswith(".chk"): - with open(filename, "r", encoding='ascii', errors='surrogateescape') as f: + with open(filename, "r", encoding="ascii", errors="surrogateescape") as f: check_file_contents.append(f.read()) # run coverage analysis report on dungeon database @@ -236,14 +256,20 @@ if __name__ == "__main__": colspan = 10 - len(cat_keys) for key in cat_keys: headers_html += HTML_CATEGORY_HEADER_CELL.format(key) - category_html = HTML_CATEGORY_HEADER.format(colspan=colspan, label=category["name"], cells=headers_html) + category_html = HTML_CATEGORY_HEADER.format( + colspan=colspan, label=category["name"], cells=headers_html + ) # render message coverage row for message_id, covered in cat_messages: category_html_row = "" for key, value in covered.items(): - category_html_row += HTML_CATEGORY_COVERAGE_CELL.format("uncovered" if not value else "covered") - category_html += HTML_CATEGORY_ROW.format(id=message_id,colspan=colspan, cells=category_html_row) + category_html_row += HTML_CATEGORY_COVERAGE_CELL.format( + "uncovered" if not value else "covered" + ) + category_html += HTML_CATEGORY_ROW.format( + id=message_id, colspan=colspan, cells=category_html_row + ) categories_html += HTML_CATEGORY_SECTION.format(id=name, rows=category_html) # render category summaries @@ -260,16 +286,22 @@ if __name__ == "__main__": # render HTML report try: - with open(HTML_TEMPLATE_PATH, "r", encoding='ascii', errors='surrogateescape') as f: + with open( + HTML_TEMPLATE_PATH, "r", encoding="ascii", errors="surrogateescape" + ) as f: # read in HTML template html_template = f.read() except IOError as e: - print('ERROR: reading HTML report template failed ({})'.format(e.strerror)) + print("ERROR: reading HTML report template failed ({})".format(e.strerror)) sys.exit(-1) # parse template with report and write it out try: - with open(html_output_path, "w", encoding='ascii', errors='surrogateescape') as f: - f.write(html_template.format(categories=categories_html, summary=summary_html)) + with open( + html_output_path, "w", encoding="ascii", errors="surrogateescape" + ) as f: + f.write( + html_template.format(categories=categories_html, summary=summary_html) + ) except IOError as e: - print('ERROR: writing HTML report failed ({})'.format(e.strerror)) + print("ERROR: writing HTML report failed ({})".format(e.strerror)) -- 2.31.1