diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e15a45655..0035ac460 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,8 +16,14 @@ jobs: - name: ShellCheck uses: ludeeus/action-shellcheck@master - - name: Run tests - run: ./extra/tests.sh + - name: Fallout tests + uses: BGforgeNet/fallout-tests@master + with: + scripts_h: scripts_src/headers/scripts.h + scripts_lst: data/scripts/scripts.lst + scripts_dir: scripts_src + dialog_dir: data/text/english/dialog + worldmap_path: data/data/worldmap.txt - uses: devopsx/gha-ubuntu-i386-fix@master diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 4bae03f6a..e859943b4 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -12,5 +12,11 @@ jobs: - name: ShellCheck uses: ludeeus/action-shellcheck@master - - name: Run tests - run: ./extra/tests.sh + - name: Fallout tests + uses: BGforgeNet/fallout-tests@master + with: + scripts_h: scripts_src/headers/scripts.h + scripts_lst: data/scripts/scripts.lst + scripts_dir: scripts_src + dialog_dir: data/text/english/dialog + worldmap_path: data/data/worldmap.txt diff --git a/extra/tests.sh b/extra/tests.sh deleted file mode 100755 index 7e33408d9..000000000 --- a/extra/tests.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -xeu -o pipefail - -./extra/tests/scripts-lst.py scripts_src/headers/scripts.h data/scripts/scripts.lst -./extra/tests/lvars.py data/scripts/scripts.lst scripts_src -./extra/tests/dialogs.py diff --git a/extra/tests/dialogs.py b/extra/tests/dialogs.py deleted file mode 100755 index be9fb1a22..000000000 --- a/extra/tests/dialogs.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python3 -# coding: utf-8 - -# finds inconsistencies between ssl and msg - -import os -from glob import glob -import re - -script_paths = [ - y for x in os.walk("scripts_src/") for y in glob(os.path.join(x[0], "*.ssl")) -] - -message_count = 0 -g_dialog_path = "data/text/english/dialog/generic.msg" -g_dialog_messages = [] -with open(g_dialog_path, encoding="cp1252") as fdialog: - for line in fdialog: - g_dialog_messages.extend(re.findall(r"\{([0-9]{3,5})\}", line)) - -for script_path in script_paths: - script_messages = [] - g_script_messages = [] - with open(script_path) as fscript: - script_text = fscript.read() - lines = re.sub(r"/\*.+?\*/", "", script_text, flags=re.DOTALL).split("\n") - for line in lines: - if line.lstrip().startswith("//"): - continue - script_messages.extend( - re.findall( - r"[^_]+(?:display_mstr|floater|dude_floater|Reply|GOption|GLowOption|NOption|NLowOption|BOption|BLowOption|GMessage|NMessage|BMessage) *\( *([0-9]{3,5}) *[,\)]", - line, - ) - ) - script_messages.extend(re.findall(r"[^_]+mstr *\( *([0-9]{3,5}) *\)", line)) - m = re.search( - r"[^_]+(?:floater_rand|Reply_Rand) *\( *([0-9]{3,5}) *, *([0-9]{3,5})", - line, - ) - if m: - script_messages.extend( - [str(i) for i in range(int(m.group(1)), int(m.group(2)) + 1)] - ) - g_script_messages.extend( - re.findall(r"[^_]+g_mstr *\( *([0-9]{3,5}) *\)", line) - ) - script_messages = list(dict.fromkeys(script_messages)) - g_script_messages = list(dict.fromkeys(g_script_messages)) - - m = re.search(r"#define NAME +SCRIPT_([A-Z0-9_]+)", script_text) - if not m: - m = re.search(".+/(.+)\.ssl", script_path) - dialog_path = "data/text/english/dialog/" + m.group(1).lower() + ".msg" - dialog_messages = [] - try: - with open(dialog_path, encoding="cp1252") as fdialog: - for line in fdialog: - dialog_messages.extend(re.findall(r"\{([0-9]{3,5})\}", line)) - except IOError: - continue - script_only = [item for item in script_messages if item not in dialog_messages] - if script_only: - print( - "Messages in " - + script_path - + " that missed in " - + dialog_path - + ": " - + " ".join(script_only) - ) - message_count += len(script_messages) - - g_script_only = [ - item for item in g_script_messages if item not in g_dialog_messages - ] - if g_script_only: - print( - "Generic messages in " - + script_path - + " that missed in " - + g_dialog_path - + ": " - + " ".join(g_script_only) - ) - message_count += len(g_script_messages) - -print("Messages tested: " + str(message_count)) diff --git a/extra/tests/lvars.py b/extra/tests/lvars.py deleted file mode 100755 index 01feffb83..000000000 --- a/extra/tests/lvars.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -# coding: utf-8 - -# checks if there are enough lvars allowed in scripts.lst - -import sys -import re -import os - -scripts_lst = sys.argv[1] -scripts_dir = sys.argv[2] - -lvars = {} - -with open(scripts_lst) as f: - linenum = 0 - for line in f: - linenum += 1 - match = re.match(r"^(\w+)\.int.*local_vars=(\d+)", line) - name = match[1].lower() - num_lvars = int(match[2]) - if not name in lvars: # scripts.lst uses first entry - lvars[name] = num_lvars - - -def get_max_lvar(fpath): - max_lvar = 0 - with open(fpath) as f: - for line in f: - match = re.match(r"^#define\s+LVAR_\w+\s+\((\d+)\)\s+.*", line) - if match: - cur_lvar = int(match[1]) - if cur_lvar > max_lvar: - max_lvar = cur_lvar - return max_lvar - - -for dir_name, subdir_list, file_list in os.walk(scripts_dir, topdown=False): - for file_name in file_list: - if file_name.endswith(".ssl"): - path = os.path.join(dir_name, file_name) - max_lvar = get_max_lvar(path) - script_name = os.path.splitext(file_name) - if script_name in lvars and lvars[script_name] < max_lvar: - print( - "Script {} has {} LVARs defined, but scripts.lst only allows {}.".format( - script_name, max_lvar, lvars[script_name] - ) - ) - sys.exit(1) diff --git a/extra/tests/requirements.txt b/extra/tests/requirements.txt deleted file mode 100644 index 6c042a374..000000000 --- a/extra/tests/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -black>=22.10.0 diff --git a/extra/tests/scripts-lst.py b/extra/tests/scripts-lst.py deleted file mode 100755 index a86ba0748..000000000 --- a/extra/tests/scripts-lst.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -# coding: utf-8 - -import sys -import re - -scripts_h = sys.argv[1] -scripts_lst = sys.argv[2] - -h_by_num = {} # num > name -h_by_name = {} # name > num -lst_by_num = {} # linenum > name -lst_by_name = {} # name > linenum -warning = False - -with open(scripts_h) as f: - for line in f: - match = re.match(r"^#define\s+SCRIPT_(\w+)\s+\((\d+)\)\s+.*", line) - if match: - h_by_num[int(match[2])] = match[1] - h_by_name[match[1]] = int(match[2]) - -with open(scripts_lst) as f: - linenum = 0 - for line in f: - linenum += 1 - scr = line.split(".", maxsplit=1)[0].upper() - lst_by_num[linenum] = scr - lst_by_name[scr] = linenum - -# search dupes in scripts.lst -lst_names = [lst_by_num[x] for x in lst_by_num] -lst_duped_names = sorted(set([x for x in lst_names if lst_names.count(x) > 1])) -lst_duped_names = [x for x in lst_duped_names if x != "RESERVED"] -for n in lst_duped_names: - duped_lines = [x for x in lst_by_num if lst_by_num[x] == n] - dupes_str = ", ".join([str(x) for x in duped_lines]) - print("Dupe: {} is defined on lines {} in scripts.lst".format(n, dupes_str)) - warning = True - -# search mismatched names and missing scripts.h defines -for i in range(1, len(lst_by_num)): - try: - if lst_by_num[i] != h_by_num[i]: - print( - "Mismatch: scripts.lst {}, scripts.h {}".format( - lst_by_num[i], h_by_num[i] - ) - ) - warning = True - except: - if (lst_by_num[i] not in h_by_name) and (lst_by_num[i] != "RESERVED"): - print( - "Missing: script {}.int, line number {} in scripts.lst is absent from scripts.h".format( - lst_by_num[i], i - ) - ) - warning = True - -if warning: - sys.exit(1)