Пример #1
0
def test_non_custom_with_custom_should_raise():
    with pytest.raises(ValueError) as err:
        StartingResources.from_non_custom_configuration(
            StartingResourcesConfiguration.CUSTOM)

    assert str(
        err.value
    ) == "from_non_custom_configuration shouldn't receive CUSTOM configuration"
Пример #2
0
def test_create_spawn_point_field(echoes_resource_database, empty_patches):
    # Setup
    patches = empty_patches.assign_starting_location(AreaLocation(100, 5000))
    capacities = [{
        'amount':
        starting_resources._vanilla_item_loss_enabled_items.get(item.index, 0),
        'index':
        item.index
    } for item in echoes_resource_database.item]

    # Run
    result = patcher_file._create_spawn_point_field(
        echoes_resource_database,
        StartingResources.from_non_custom_configuration(
            StartingResourcesConfiguration.VANILLA_ITEM_LOSS_ENABLED), patches)

    # Assert
    assert result == {
        "location": {
            "world_asset_id": 100,
            "area_asset_id": 5000,
        },
        "amount": capacities,
        "capacity": capacities,
    }
Пример #3
0
def test_round_trip_json_all_zero_items(all_zero_starting_resources):
    # Run
    round_trip = StartingResources.from_json(
        all_zero_starting_resources.as_json)

    # Assert
    assert all_zero_starting_resources == round_trip
Пример #4
0
 def layout_configuration_starting_resources(
         self, value: StartingResourcesConfiguration):
     self._check_editable_and_mark_dirty()
     self._layout_configuration = dataclasses.replace(
         self.layout_configuration,
         starting_resources=StartingResources.from_non_custom_configuration(
             value))
Пример #5
0
def test_distribute_command_logic(mock_generate_list: MagicMock, ):
    # Setup
    args = MagicMock()
    args.trick_level = LayoutTrickLevel.HARD.value
    args.major_items_mode = False
    args.sky_temple_keys = LayoutSkyTempleKeyMode.ALL_BOSSES.value
    args.skip_item_loss = True
    args.seed = 15000
    args.output_file = "asdfasdf/qwerqwerqwer/zxcvzxcv.json"

    # Run
    echoes.distribute_command_logic(args)

    # Assert
    mock_generate_list.assert_called_once_with(permalink=Permalink(
        seed_number=args.seed,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level=LayoutTrickLevel.HARD,
            sky_temple_keys=LayoutSkyTempleKeyMode.ALL_BOSSES,
            elevators=LayoutRandomizedFlag.VANILLA,
            pickup_quantities={},
            starting_location=StartingLocation.default(),
            starting_resources=StartingResources.from_non_custom_configuration(
                StartingResourcesConfiguration.VANILLA_ITEM_LOSS_DISABLED),
        ),
    ),
                                               status_update=ANY)

    save_file_mock: MagicMock = mock_generate_list.return_value.save_to_file
    save_file_mock.assert_called_once_with(Path(args.output_file))
Пример #6
0
 def default(cls) -> "LayoutConfiguration":
     return cls.from_params(
         trick_level=LayoutTrickLevel.NO_TRICKS,
         sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
         elevators=LayoutRandomizedFlag.VANILLA,
         pickup_quantities={},
         starting_location=StartingLocation.default(),
         starting_resources=StartingResources.default(),
     )
Пример #7
0
def test_raise_for_pickup_above_maximum():
    database = default_database.default_prime2_resource_database()

    with pytest.raises(ValueError) as err:
        StartingResources(StartingResourcesConfiguration.CUSTOM,
                          {item: 10
                           for item in database.item})

    assert str(err.value) == "Item I: Power Beam has a maximum of 1, got 10"
Пример #8
0
def get_layout_configuration_from_args(args) -> LayoutConfiguration:
    return LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel(args.trick_level),
        sky_temple_keys=LayoutSkyTempleKeyMode(args.sky_temple_keys),
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.from_item_loss(
            not args.skip_item_loss),
    )
Пример #9
0
 def from_json_dict(cls, json_dict: dict) -> "LayoutConfiguration":
     return cls.from_params(
         trick_level=LayoutTrickLevel(json_dict["trick_level"]),
         sky_temple_keys=LayoutSkyTempleKeyMode(
             json_dict["sky_temple_keys"]),
         elevators=LayoutRandomizedFlag(json_dict["elevators"]),
         pickup_quantities=json_dict["pickup_quantities"],
         starting_location=StartingLocation.from_json(
             json_dict["starting_location"]),
         starting_resources=StartingResources.from_json(
             json_dict["starting_resources"]),
     )
Пример #10
0
def test_create_patches(
    mock_random: MagicMock,
    mock_calculate_item_pool: MagicMock,
    mock_create_base_patches: MagicMock,
    mock_retcon_playthrough_filler: MagicMock,
    mock_indices_for_unassigned_pickups: MagicMock,
):
    # Setup
    seed_number: int = 91319
    game = default_prime2_game_description()
    status_update: Union[MagicMock, Callable[[str], None]] = MagicMock()
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.from_item_loss(False),
    )
    permalink = Permalink(
        seed_number=seed_number,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    mock_calculate_item_pool.return_value = list(
        sorted(game.pickup_database.original_pickup_mapping.values()))
    mock_create_base_patches.return_value.starting_location = game.starting_location
    mock_create_base_patches.return_value.custom_initial_items = None

    filler_patches = mock_retcon_playthrough_filler.return_value

    # Run
    result = generator._create_patches(permalink, game, status_update)

    # Assert
    mock_random.assert_called_once_with(permalink.as_str)
    mock_calculate_item_pool.assert_called_once_with(permalink, game)

    mock_create_base_patches.assert_called_once_with(mock_random.return_value,
                                                     game, permalink, ANY)

    mock_retcon_playthrough_filler.assert_called_once_with(
        ANY, ANY, ANY, mock_random.return_value, status_update)

    mock_indices_for_unassigned_pickups.assert_called_once_with(
        mock_random.return_value, game, filler_patches.pickup_assignment, ANY)
    filler_patches.assign_new_pickups.assert_called_once_with(
        mock_indices_for_unassigned_pickups.return_value)

    assert result == filler_patches.assign_new_pickups.return_value
Пример #11
0
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data, False)
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    logic, state = logic_bootstrap(configuration, game,
                                   GamePatches.with_game(game))

    return logic, state, permalink
Пример #12
0
def test_generate_seed_with_invalid_quantity_configuration():
    # Setup
    status_update = MagicMock()

    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={"Light Suit": 5},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )

    permalink = Permalink(
        seed_number=50,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )

    # Run
    with pytest.raises(randovania.resolver.exceptions.GenerationFailure):
        generator.generate_list(permalink, status_update=status_update)
Пример #13
0
def test_decode_v1(mock_dictionary_byte_hash: MagicMock):
    mock_dictionary_byte_hash.return_value = 120
    # We're mocking the database hash to avoid breaking tests every single time we change the database

    # This test should break whenever we change how permalinks are created
    # When this happens, we must bump the permalink version and change the tests
    encoded = "IAAAfReNPArRHMClxLYgIID3"

    expected = Permalink(
        seed_number=1000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration(
            disable_hud_popup=True,
            menu_mod=True,
            speed_up_credits=False,
        ),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level=LayoutTrickLevel.HARD,
            sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
            elevators=LayoutRandomizedFlag.RANDOMIZED,
            pickup_quantities={
                "Missile Expansion": 10,
                "Light Suit": 9,
            },
            starting_location=StartingLocation.default(),
            starting_resources=StartingResources.default(),
        ),
    )

    # Uncomment this line to quickly get the new encoded permalink
    # assert expected.as_str == ""

    # Run
    link = Permalink.from_str(encoded)

    # Assert
    assert link == expected
Пример #14
0
def test_apply_layout(mock_run_with_args: MagicMock,
                      mock_base_args: MagicMock,
                      mock_ensure_no_menu_mod: MagicMock,
                      mock_create_pak_backups: MagicMock,
                      mock_calculate_indices: MagicMock,
                      mock_add_menu_mod_to_files: MagicMock,
                      mock_create_progress_update_from_successive_messages: MagicMock,
                      mock_save_to_file: MagicMock,
                      seed_number: int,
                      item_loss: bool,
                      elevators: bool,
                      warp_to_start: bool,
                      include_menu_mod: bool,
                      speed_up_credits: bool,
                      ):
    # Setup
    hud_memo_popup_removal: bool = MagicMock()
    cosmetic_patches = CosmeticPatches(disable_hud_popup=hud_memo_popup_removal,
                                       speed_up_credits=speed_up_credits,
                                       )
    description = LayoutDescription(
        version=randovania.VERSION,
        permalink=Permalink(
            seed_number=seed_number,
            spoiler=False,
            patcher_configuration=PatcherConfiguration(
                menu_mod=include_menu_mod,
                warp_to_start=warp_to_start,
            ),
            layout_configuration=LayoutConfiguration.from_params(
                trick_level=MagicMock(),
                sky_temple_keys=MagicMock(),
                elevators=LayoutRandomizedFlag.RANDOMIZED if elevators else LayoutRandomizedFlag.VANILLA,
                pickup_quantities={},
                starting_location=StartingLocation.default(),
                starting_resources=StartingResources.from_item_loss(item_loss),
            )
        ),
        patches=None,
        solver_path=(),
    )

    game_root = MagicMock(spec=Path())
    backup_files_path = MagicMock()
    progress_update = MagicMock()
    status_update = mock_create_progress_update_from_successive_messages.return_value

    mock_calculate_indices.return_value = [10, 25, 1, 2, 5, 1]
    mock_base_args.return_value = []
    expected_args = [
        "-s", str(seed_number),
        "-p", "10,25,1,2,5,1"
    ]
    if not item_loss:
        expected_args.append("-i")
    if elevators:
        expected_args.append("-v")
    if speed_up_credits:
        expected_args.append("-c")
    if warp_to_start:
        expected_args.append("-t")

    # Run
    claris_randomizer.apply_layout(description, cosmetic_patches, backup_files_path, progress_update, game_root)

    # Assert
    mock_base_args.assert_called_once_with(game_root, hud_memo_popup_removal=hud_memo_popup_removal)
    mock_create_progress_update_from_successive_messages.assert_called_once_with(
        progress_update,
        400 if include_menu_mod else 100
    )
    mock_ensure_no_menu_mod.assert_called_once_with(game_root, backup_files_path, status_update)
    mock_create_pak_backups.assert_called_once_with(game_root, backup_files_path, status_update)
    mock_calculate_indices.assert_called_once_with(description)
    game_root.joinpath.assert_called_once_with("files", "randovania.json")
    mock_save_to_file.assert_called_once_with(description, game_root.joinpath.return_value)
    mock_run_with_args.assert_called_once_with(expected_args, "Randomized!", status_update)
    if include_menu_mod:
        mock_add_menu_mod_to_files.assert_called_once_with(game_root, status_update)
    else:
        mock_add_menu_mod_to_files.assert_not_called()
Пример #15
0
def _simple_starting_resources(request):
    yield StartingResources.from_non_custom_configuration(request.param)
Пример #16
0
def _all_zero_starting_resources():
    database = default_database.default_prime2_resource_database()
    return StartingResources(StartingResourcesConfiguration.CUSTOM,
                             {item: 0
                              for item in database.item})
Пример #17
0
    # Assert
    assert result == {
        "version": 4,
        "options": {}
    }


_sample_layout_configurations = [
    {
        "trick_level": trick_level,
        "sky_temple_keys": LayoutSkyTempleKeyMode.FULLY_RANDOM,
        "elevators": LayoutRandomizedFlag.RANDOMIZED,
        "pickup_quantities": {},
        "starting_location": StartingLocation.default(),
        "starting_resources": StartingResources.from_item_loss(item_loss),
    }
    for trick_level in [LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.HARD, LayoutTrickLevel.MINIMAL_RESTRICTIONS]
    for item_loss in (False, True)
]


@pytest.fixture(params=_sample_layout_configurations, name="initial_layout_configuration_params")
def _initial_layout_configuration_params(request) -> dict:
    return request.param


@pytest.mark.parametrize("new_trick_level",
                         [LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.TRIVIAL, LayoutTrickLevel.HYPERMODE])
def test_edit_layout_trick_level(option: Options,
                                 initial_layout_configuration_params: dict,
Пример #18
0
def test_default():
    value = StartingResources.default()

    # Assert
    assert value.configuration == StartingResourcesConfiguration.VANILLA_ITEM_LOSS_ENABLED
Пример #19
0
def test_round_trip_json_simple(simple_starting_resources):
    # Run
    round_trip = StartingResources.from_json(simple_starting_resources.as_json)

    # Assert
    assert simple_starting_resources == round_trip
Пример #20
0
def test_missing_item_for_constructor_should_raise():
    with pytest.raises(ValueError) as err:
        StartingResources(StartingResourcesConfiguration.CUSTOM, {})

    assert str(err.value).startswith("resources {} has missing items: ")
Пример #21
0
        menu_mod=True,
        warp_to_start=False,
    ),
])
@pytest.mark.parametrize("layout", [
    LayoutConfiguration.default(),
    LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.HARD,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.RANDOMIZED,
        pickup_quantities={
            "Missile Expansion": 10,
            "Light Suit": 9,
        },
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    ),
])
def test_round_trip(spoiler: bool, patcher: PatcherConfiguration,
                    layout: LayoutConfiguration):
    # Setup
    link = Permalink(
        seed_number=1000,
        spoiler=spoiler,
        patcher_configuration=patcher,
        layout_configuration=layout,
    )

    # Run
    after = Permalink.from_str(link.as_str)
Пример #22
0
    # Assert
    assert result == {"version": 6, "options": {}}


_sample_layout_configurations = [{
    "trick_level":
    trick_level,
    "sky_temple_keys":
    LayoutSkyTempleKeyMode.FULLY_RANDOM,
    "elevators":
    LayoutRandomizedFlag.RANDOMIZED,
    "pickup_quantities": {},
    "starting_location":
    StartingLocation.default(),
    "starting_resources":
    StartingResources.from_item_loss(item_loss),
} for trick_level in [
    LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.HARD,
    LayoutTrickLevel.MINIMAL_RESTRICTIONS
] for item_loss in (False, True)]


@pytest.fixture(params=_sample_layout_configurations,
                name="initial_layout_configuration_params")
def _initial_layout_configuration_params(request) -> dict:
    return request.param


@pytest.mark.parametrize("new_trick_level", [
    LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.TRIVIAL,
    LayoutTrickLevel.HYPERMODE