<commit_before>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Rulesets;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
using osu.Game.Screens.Select.Filter;

namespace osu.Game.Tests.Visual.SongSelect
{
    [TestFixture]
    public class TestSceneBeatmapCarousel : OsuTestScene
    {
        private TestBeatmapCarousel carousel;
        private RulesetStore rulesets;

        public override IReadOnlyList<Type> RequiredTypes => new[]
        {
            typeof(CarouselItem),
            typeof(CarouselGroup),
            typeof(CarouselGroupEagerSelect),
            typeof(CarouselBeatmap),
            typeof(CarouselBeatmapSet),

            typeof(DrawableCarouselItem),
            typeof(CarouselItemState),

            typeof(DrawableCarouselBeatmap),
            typeof(DrawableCarouselBeatmapSet),
        };

        private readonly Stack<BeatmapSetInfo> selectedSets = new Stack<BeatmapSetInfo>();
        private readonly HashSet<int> eagerSelectedIDs = new HashSet<int>();

        private BeatmapInfo currentSelection => carousel.SelectedBeatmap;

        private const int set_count = 5;

        [BackgroundDependencyLoader]
        private void load(RulesetStore rulesets)
        {
            this.rulesets = rulesets;
        }

        /// <summary>
        /// Test keyboard traversal
        /// </summary>
        [Test]
        public void TestTraversal()
        {
            loadBeatmaps();

            advanceSelection(direction: 1, diff: false);
            waitForSelection(1, 1);

            advanceSelection(direction: 1, diff: true);
            waitForSelection(1, 2);

            advanceSelection(direction: -1, diff: false);
            waitForSelection(set_count, 1);

            advanceSelection(direction: -1, diff: true);
            waitForSelection(set_count - 1, 3);

            advanceSelection(diff: false);
            advanceSelection(diff: false);
            waitForSelection(1, 2);

            advanceSelection(direction: -1, diff: true);
            advanceSelection(direction: -1, diff: true);
            waitForSelection(set_count, 3);
        }

        [TestCase(true)]
        [TestCase(false)]
        public void TestTraversalHold(bool forwards)
        {
            var sets = new List<BeatmapSetInfo>();
            const int create_this_many_sets = 200;

            for (int i = 0; i < create_this_many_sets; i++)
            {
                var set = createTestBeatmapSet(i + 1);
                sets.Add(set);
            }

            loadBeatmaps(sets);

            void selectNextAndAssert(int amount)
            {
                setSelected(forwards ? 1 : create_this_many_sets, 1);
                string text = forwards ? "Next" : "Previous";
                AddStep($"{text} beatmap {amount} times", () =>
                {
                    for (int i = 0; i < amount; i++)
                    {
                        carousel.SelectNext(forwards ? 1 : -1);
                    }
                });
                waitForSelection(forwards ? amount + 1 : create_this_many_sets - amount);
            }

            for (int i = 1; i < create_this_many_sets; i += i)
            {
                selectNextAndAssert(i);
            }
        }

        /// <summary>
        /// Test filtering
        /// </summary><commit_msg>Cover skipDifficulties = false in tests<commit_after>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Rulesets;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
using osu.Game.Screens.Select.Filter;

namespace osu.Game.Tests.Visual.SongSelect
{
    [TestFixture]
    public class TestSceneBeatmapCarousel : OsuTestScene
    {
        private TestBeatmapCarousel carousel;
        private RulesetStore rulesets;

        public override IReadOnlyList<Type> RequiredTypes => new[]
        {
            typeof(CarouselItem),
            typeof(CarouselGroup),
            typeof(CarouselGroupEagerSelect),
            typeof(CarouselBeatmap),
            typeof(CarouselBeatmapSet),

            typeof(DrawableCarouselItem),
            typeof(CarouselItemState),

            typeof(DrawableCarouselBeatmap),
            typeof(DrawableCarouselBeatmapSet),
        };

        private readonly Stack<BeatmapSetInfo> selectedSets = new Stack<BeatmapSetInfo>();
        private readonly HashSet<int> eagerSelectedIDs = new HashSet<int>();

        private BeatmapInfo currentSelection => carousel.SelectedBeatmap;

        private const int set_count = 5;

        [BackgroundDependencyLoader]
        private void load(RulesetStore rulesets)
        {
            this.rulesets = rulesets;
        }

        /// <summary>
        /// Test keyboard traversal
        /// </summary>
        [Test]
        public void TestTraversal()
        {
            loadBeatmaps();

            advanceSelection(direction: 1, diff: false);
            waitForSelection(1, 1);

            advanceSelection(direction: 1, diff: true);
            waitForSelection(1, 2);

            advanceSelection(direction: -1, diff: false);
            waitForSelection(set_count, 1);

            advanceSelection(direction: -1, diff: true);
            waitForSelection(set_count - 1, 3);

            advanceSelection(diff: false);
            advanceSelection(diff: false);
            waitForSelection(1, 2);

            advanceSelection(direction: -1, diff: true);
            advanceSelection(direction: -1, diff: true);
            waitForSelection(set_count, 3);
        }

        [TestCase(true)]
        [TestCase(false)]
        public void TestTraversalHold(bool forwards)
        {
            var sets = new List<BeatmapSetInfo>();
            const int create_this_many_sets = 200;

            for (int i = 0; i < create_this_many_sets; i++)
            {
                var set = createTestBeatmapSet(i + 1);
                sets.Add(set);
            }

            loadBeatmaps(sets);

            void selectNextAndAssert(int amount)
            {
                setSelected(forwards ? 1 : create_this_many_sets, 1);
                string text = forwards ? "Next" : "Previous";
                AddStep($"{text} beatmap {amount} times", () =>
                {
                    for (int i = 0; i < amount; i++)
                    {
                        carousel.SelectNext(forwards ? 1 : -1);
                    }
                });
                waitForSelection(forwards ? amount + 1 : create_this_many_sets - amount);
            }

            for (int i = 1; i < create_this_many_sets; i += i)
            {
                selectNextAndAssert(i);
            }
        }

        [Test]
        public void TestTraversalHoldDifficulties()
        {
            var sets = new List<BeatmapSetInfo>();

            for (int i = 0; i < 20; i++)
            {
                var set = createTestBeatmapSet(i + 1);
                sets.Add(set);
            }

            loadBeatmaps(sets);

            void selectNextAndAssert(int amount, bool forwards, int expectedSet, int expectedDiff)
            {
                // Select very first or very last difficulty
                setSelected(forwards ? 1 : 20, forwards ? 1 : 3);
                string text = forwards ? "Next" : "Previous";
                AddStep($"{text} difficulty {amount} times", () =>
                {
                    for (int i = 0; i < amount; i++)
                    {
                        carousel.SelectNext(forwards ? 1 : -1, false);
                    }
                });
                waitForSelection(expectedSet, expectedDiff);
            }

            // Selects next set once, difficulty index doesn't change
            selectNextAndAssert(3, true, 2, 1);
            // Selects next set 16 times (50 // 3 == 16), difficulty index changes twice (50 % 3 == 2)
            selectNextAndAssert(50, true, 17, 3);
            // Travels around the carousel thrice (200/60 == 3)
            // continues to select 20 times (200 % 60 == 20)
            // selects next set 6 times (20 // 3 == 6)
            // difficulty index changes twice (20 % 3 == 2)
            selectNextAndAssert(200, true, 7, 3);

            // All same but in reverse
            selectNextAndAssert(3, false, 19, 3);
            selectNextAndAssert(50, false, 4, 1);
            selectNextAndAssert(200, false, 14, 1);
        }

        /// <summary>
        /// Test filtering
        /// </summary>
{'fraction_non_alphanumeric': 0.09827271751957944, 'fraction_numerical': 0.014161570646926296, 'mean_word_length': 1.797719087635054, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '676204', 'n_tokens_mistral': 2658, 'n_tokens_neox': 2434, 'n_words': 616}