示例#1
0
 def test_load_file_object(self):
     """Tests if D2TXT can load a TXT file from a file object."""
     d2txt = D2TXT.load_txt(
         StringIO(
             "column 1\tcolumn 2\tcolumn 3\r\n"
             "value 1\tvalue 2\tvalue 3\r\n"
             "foo\tbar\tbaz\r\n",
             newline="",  # Required to make csv.reader work correctly
         ))
     self.compare_d2txt(
         d2txt,
         ["column 1", "column 2", "column 3"],
         [["value 1", "value 2", "value 3"], ["foo", "bar", "baz"]],
     )
示例#2
0
    def test_save_to_file_object(self):
        """Tests if D2TXT can be saved to a file object."""
        d2txt = D2TXT(["column 1", "column 2", "column 3"])
        d2txt.extend([["value 1", "value 2", "value 3"], ["foo", "bar",
                                                          "baz"]])

        # newline='' is required to make csv.writer work correctly
        txtfile = StringIO(newline="")
        d2txt.to_txt(txtfile)
        self.assertEqual(
            txtfile.getvalue(),
            "column 1\tcolumn 2\tcolumn 3\r\n"
            "value 1\tvalue 2\tvalue 3\r\n"
            "foo\tbar\tbaz\r\n",
        )
示例#3
0
    def test_column_name_whitespace(self):
        """Tests if whitespace in columns are preserved when saved to a file."""
        d2txt = D2TXT(
            ["   column 1", "column 2    ", "  column 3  ", "", "  "])
        d2txt.extend(
            [["3 before", "4 after", "2 both", "empty", "spaces only"]])

        # newline='' is required to make csv.writer work correctly
        txtfile = StringIO(newline="")
        d2txt.to_txt(txtfile)
        self.assertEqual(
            txtfile.getvalue(),
            "   column 1\tcolumn 2    \t  column 3  \t\t  \r\n"
            "3 before\t4 after\t2 both\tempty\tspaces only\r\n",
        )
示例#4
0
    def test_cell_access(self):
        """Tests if cells can be accessed using row indices and column names."""
        d2txt = D2TXT(["column 1", "column 2", "column 3"])

        d2txt.append(["foo", "bar", "baz"])
        self.assertEqual(d2txt[0]["column 1"], "foo")
        self.assertEqual(d2txt[0]["column 2"], "bar")
        self.assertEqual(d2txt[0]["column 3"], "baz")

        d2txt[0]["column 1"] = "alpha"
        d2txt[0]["column 2"] = "beta"
        d2txt[0]["column 3"] = "gamma"
        self.assertEqual(d2txt[0]["column 1"], "alpha")
        self.assertEqual(d2txt[0]["column 2"], "beta")
        self.assertEqual(d2txt[0]["column 3"], "gamma")
示例#5
0
def main(argv):
    """Entrypoint of the command line script."""
    arg_parser = argparse.ArgumentParser(__doc__)
    arg_parser.add_argument("itemtypes_txt", help="Path to ItemTypes.txt")
    arg_parser.add_argument("weapons_txt", help="Path to Weapons.txt")

    args = arg_parser.parse_args(argv)

    item_types_txt = D2TXT.load_txt(args.itemtypes_txt)
    weapons_txt = D2TXT.load_txt(args.weapons_txt)

    itype_nodes = parse_itypes(item_types_txt)

    one_handers, two_handers, mixed_types = classify_itypes_by_hand(
        itype_nodes, weapons_txt
    )
    print("One-handers: " + ", ".join(one_handers))
    print("Two-handers: " + ", ".join(two_handers))
    print("Mixed bags : " + ", ".join(mixed_types))
    print("-" * 80)

    for node in itype_nodes.values():
        if not node.parents:
            print_itype_tree(node, one_handers=one_handers, two_handers=two_handers)
示例#6
0
    def test_assign_list(self):
        """Tests if D2TXT accepts direct assignment using lists."""
        d2txt = D2TXT(["column 1", "column 2", "column 3"])

        d2txt.extend([[]] * 3)
        d2txt[0] = []
        d2txt[1] = ["foo", "bar"]
        d2txt[2] = ["1", "2", "3", "these", "strings", "are", "ignored"]

        self.assertEqual(len(d2txt), 3)
        for i, row in enumerate(d2txt):
            with self.subTest(i=i):
                self.assertEqual(len(row), 3)

        self.assertEqual(list(d2txt[0].values()), [None, None, None])
        self.assertEqual(list(d2txt[1].values()), ["foo", "bar", None])
        self.assertEqual(list(d2txt[2].values()), ["1", "2", "3"])
示例#7
0
    def test_save_to_path(self):
        """Tests if D2TXT can be saved to a file path."""
        d2txt = D2TXT(["column 1", "column 2", "column 3"])
        d2txt.extend([["value 1", "value 2", "value 3"], ["foo", "bar",
                                                          "baz"]])

        d2txt.to_txt(type(self).save_txt_path)
        # newline='' is required to make csv.writer work correctly
        with open(type(self).save_txt_path, newline="") as save_txt:
            saved_contents = save_txt.read()

        self.assertEqual(
            saved_contents,
            "column 1\tcolumn 2\tcolumn 3\r\n"
            "value 1\tvalue 2\tvalue 3\r\n"
            "foo\tbar\tbaz\r\n",
        )
示例#8
0
    def test_column_name_case_sensitivity(self):
        """Tests if column names are case-sensitive."""
        d2txt = D2TXT(["column name", "Column Name", "COLUMN NAME"])

        d2txt.append(["lowercase", "capital letters", "uppercase"])
        self.assertEqual(
            list(d2txt[0].values()),
            ["lowercase", "capital letters", "uppercase"],
        )
        with self.assertRaises(KeyError):
            d2txt[0]["column NAME"]  # pylint:disable=pointless-statement

        d2txt[0]["COLUMN NAME"] = "c"
        d2txt[0]["Column Name"] = "b"
        d2txt[0]["column name"] = "a"
        self.assertEqual(list(d2txt[0].values()), ["a", "b", "c"])
        with self.assertRaises(KeyError):
            d2txt[0]["column NAME"] = 1
示例#9
0
    def test_insert_list(self):
        """Tests if D2TXT.insert() accepts lists."""
        d2txt = D2TXT(["column 1", "column 2", "column 3"])

        d2txt.insert(0, [])
        self.assertEqual(len(d2txt), 1)
        d2txt.insert(0, ["foo", "bar"])
        self.assertEqual(len(d2txt), 2)
        d2txt.insert(1, ["1", "2", "3", "these", "strings", "are", "ignored"])
        self.assertEqual(len(d2txt), 3)

        for i, row in enumerate(d2txt):
            with self.subTest(i=i):
                self.assertEqual(len(row), 3)

        self.assertEqual(list(d2txt[0].values()), ["foo", "bar", None])
        self.assertEqual(list(d2txt[1].values()), ["1", "2", "3"])
        self.assertEqual(list(d2txt[2].values()), [None, None, None])
示例#10
0
    def test_invalid_row_and_cell(self):
        """Tests if accessing invalid rows and cells raises appropriate exceptions."""
        d2txt = D2TXT(["column 1", "column 2", "column 3"])
        d2txt.append(["foo", "bar", "baz"])
        d2txt.append(["rabbit", "dog", "cow"])
        d2txt.append(["one", "two", "six"])

        with self.assertRaises(IndexError):
            d2txt[99]  # pylint:disable=pointless-statement
        with self.assertRaises(IndexError):
            d2txt[99] = ["mangy", "dog", "cow"]
        with self.assertRaises(IndexError):
            d2txt[99]["column 1"]  # pylint:disable=pointless-statement
        with self.assertRaises(IndexError):
            d2txt[99]["column 1"] = "cat"
        with self.assertRaises(KeyError):
            d2txt[0]["column 99"]  # pylint:disable=pointless-statement
        with self.assertRaises(KeyError):
            d2txt[0]["column 99"] = "bird"
示例#11
0
    def test_array_group_pack(self):
        """Tests if columns belonging to an array group are properly packed."""
        COLUMN_GROUPS.extend(
            initialize_column_groups(
                ("--ArrayGroup", ("column 2", "column 1", "COLUMN 4"))))
        d2txt = D2TXT(["column 1", "column 2", "column 3", "column 4"])
        d2txt.extend([["foo", "bar", 225, 45]])

        self.assertEqual(
            d2txt_to_toml(d2txt),
            "columns = [\n"
            "  'column 1',\n  'column 2',\n  'column 3',\n  'column 4',\n"
            "]\n\n"
            "[column_groups]\n"
            "--ArrayGroup = ['column 2', 'column 1', 'column 4']\n\n"
            "[[rows]]\n"
            "--ArrayGroup = ['bar', 'foo', '45']\n"
            "'column 3' = 225\n\n",
        )
示例#12
0
    def test_bitfield_decode(self):
        """Tests if bitfields are correctly decoded when saved to TOML file."""
        d2txt = D2TXT(["aurafilter"])
        d2txt.extend([["33025"], ["0"], ["65535"], ["4294901760"]])

        self.maxDiff = None  # pylint: disable=invalid-name
        self.assertEqual(
            d2txt_to_toml(d2txt),
            "columns = [\n  'aurafilter',\n]\n\n"
            "[[rows]]\naurafilter = [['FindPlayers', 'NotInsideTowns', 'IgnoreAllies']]\n\n"
            "[[rows]]\naurafilter = [[]]\n\n"
            "[[rows]]\naurafilter = "
            "[['FindPlayers', 'FindMonsters', 'FindOnlyUndead', 'FindMissiles', "
            "'FindObjects', 'FindItems', 'FindAttackable', 'NotInsideTowns', "
            "'UseLineOfSight', 'FindSelectable', 'FindCorpses', 'NotInsideTowns2', "
            "'IgnoreBoss', 'IgnoreAllies'], [0x840]]\n\n"
            "[[rows]]\naurafilter = "
            "[['IgnoreNPC', 'IgnorePrimeEvil', 'IgnoreJustHitUnits'], [0xFFF20000]]\n\n",
        )
示例#13
0
    def test_extend_list(self):
        """Tests if D2TXT.extend() accepts lists."""
        d2txt = D2TXT(["column 1", "column 2", "column 3"])

        # Internally uses D2TXT.append(), which uses D2TXT.insert()
        d2txt.extend([[]])
        self.assertEqual(len(d2txt), 1)
        d2txt.extend([
            ["foo", "bar"],
            ["1", "2", "3", "these", "strings", "are", "ignored"],
        ])
        self.assertEqual(len(d2txt), 3)

        for i, row in enumerate(d2txt):
            with self.subTest(i=i):
                self.assertEqual(len(row), 3)

        self.assertEqual(list(d2txt[0].values()), [None, None, None])
        self.assertEqual(list(d2txt[1].values()), ["foo", "bar", None])
        self.assertEqual(list(d2txt[2].values()), ["1", "2", "3"])
示例#14
0
def main(argv):
    """Entrypoint of the command line script."""
    args = parse_args(argv)

    tcex_txt = D2TXT.load_txt(args.tcex_txt)
    tc_dict = make_tc_dict(tcex_txt)

    re_flags = 0
    if args.ignore_case:
        re_flags = re.IGNORECASE

    tc_patterns = []
    for pattern_index, pattern_str in enumerate(args.pattern):
        print(f"Pattern {pattern_index + 1}: {repr(pattern_str)}")
        tc_patterns.append(re.compile(pattern_str, flags=re_flags))

    num_matched_tcs = 0
    num_rebalanced_tcs = 0
    for tc_entry in tcex_txt:
        name = tc_entry["Treasure Class"]
        if not match_in_patterns(name, tc_patterns):
            continue

        num_matched_tcs += 1

        # Rebalance treasureclasses from top to bottom. Since a treasureclass
        # can only refer to other TCs above its row, we assume that all previous
        # TCs have already been rebalanced.
        for item_col, prob_col in TC_PROB_COLUMNS.items():
            item_name = tc_entry[item_col]
            if not item_name:
                continue
            if item_name in tc_dict and match_in_patterns(
                    item_name, tc_patterns):
                tc_entry[prob_col] = sum_probs(tc_dict[item_name])
                num_rebalanced_tcs += 1

    tcex_txt.to_txt(args.tcex_txt)
    print(f"{num_matched_tcs} treasureclass(es) matched, "
          f"{num_rebalanced_tcs} treasureclass(es) rebalanced.")
示例#15
0
    def test_falsy_cell(self):
        """Tests if falsy values in cells are preserved when saved to a file.

        Tested values include None, integer 0, float 0.0, and False.
        """
        d2txt = D2TXT(["column 1", "column 2", "column 3"])
        d2txt.extend([
            ["empty", "", ""],
            ["", "", ""],
            ["None", None, None],
            [None, None, None],
            ["integer 0", 0, 0],
            [0, 0, 0],
            ["float 0.0", 0.0, 0.0],
            [0.0, 0.0, 0.0],
            ["False", False, False],
            [False, False, False],
            ["truncated row"],
            [],
        ])

        # newline='' is required to make csv.writer work correctly
        txtfile = StringIO(newline="")
        d2txt.to_txt(txtfile)
        self.assertEqual(
            txtfile.getvalue(),
            "column 1\tcolumn 2\tcolumn 3\r\n"
            "empty\t\t\r\n"
            "\t\t\r\n"
            "None\t\t\r\n"
            "\t\t\r\n"
            "integer 0\t0\t0\r\n"
            "0\t0\t0\r\n"
            "float 0.0\t0.0\t0.0\r\n"
            "0.0\t0.0\t0.0\r\n"
            "False\tFalse\tFalse\r\n"
            "False\tFalse\tFalse\r\n"
            "truncated row\t\t\r\n"
            "\t\t\r\n",
        )
示例#16
0
    def test_load_path(self):
        """Tests if D2TXT can load a file using a file path, and its contents
        are preserved."""
        file_path = path.join(path.dirname(path.abspath(__file__)),
                              "sample.txt")
        d2txt = D2TXT.load_txt(file_path)

        self.compare_d2txt(
            d2txt,
            [
                "column name",
                "column 2",
                "column 3",
                "",
                "COLUMN NAME",
            ],
            [
                [
                    "lowercase column name",
                    "next cell is empty",
                    "",
                    "empty column name",
                    "UPPERCASE COLUMN NAME",
                ],
                [
                    "next row is empty",
                    "   leading spaces",
                    "trailing spaces   ",
                    "    surrounded by spaces  ",
                    '"double quotes"',
                ],
                ["", "", "", "", "0"],
                [
                    "this row and the next has not enough cells", None, None,
                    None, None
                ],
                [None, None, None, None, None],
            ],
        )
示例#17
0
 def test_column_assignment(self):
     """Tests column name assignment."""
     base_column_names = ["column 1", "column 2", "column 3"]
     d2txt = D2TXT(base_column_names)
     self.assertEqual(list(d2txt.column_names()), base_column_names)
示例#18
0
 def test_duplicate_column_names(self):
     """Tests if duplicate column names cause an error."""
     with self.assertRaises(DuplicateColumnNameError):
         D2TXT(["column name"] * 60)
示例#19
0
def main(argv):
    """Entrypoint of the command line script."""
    arg_parser = argparse.ArgumentParser(description=__doc__)

    arg_parser.add_argument("weapons_txt", help="Path to Weapons.txt")
    arg_parser.add_argument(
        "--1h",
        type=check_item_code,
        help="If provided, item code to assign to 1-hand weapons",
    )
    arg_parser.add_argument(
        "--2h",
        type=check_item_code,
        help="If provided, item code to assign to 2-hand weapons",
    )
    arg_parser.add_argument(
        "--both",
        type=check_item_code,
        help="If provided, item code to assign to 1-or-2-hand weapons",
    )

    args = vars(arg_parser.parse_args(argv))

    weapons_txt = D2TXT.load_txt(args["weapons_txt"])

    num_1h = num_2h = num_both = 0

    for row_index, weapon in enumerate(weapons_txt):
        if not (weapon["type"] and weapon["code"]):
            continue

        if weapon["type2"]:
            print(f"Warning: Row {row_index + 1} is skipped -- "
                  f'{weapon["name"]} already has \'type2\' assigned.')
            continue

        if weapon["1or2handed"]:
            item_code = args["both"]
            num_both += 1
        elif weapon["2handed"]:
            item_code = args["2h"]
            num_2h += 1
        else:
            item_code = args["1h"]
            num_1h += 1

        if item_code:
            weapon["type2"] = item_code

    weapons_txt.to_txt(args["weapons_txt"])

    if args["1h"]:
        print(
            f'\'{args["1h"]}\' has been assigned to {num_1h} 1-hand weapon(s)')
    if args["2h"]:
        print(
            f'\'{args["2h"]}\' has been assigned to {num_2h} 2-hand weapon(s)')
    if args["both"]:
        print(
            f'\'{args["both"]}\' has been assigned to {num_both} 1-or-2-hand weapon(s)'
        )