<commit_before>package de.danoeh.antennapod.core.storage;

import android.support.annotation.NonNull;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import de.danoeh.antennapod.core.feed.FeedFile;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.FeedMother;
import de.danoeh.antennapod.core.storage.DBWriter.ItemEnqueuePositionCalculator;
import de.danoeh.antennapod.core.storage.DBWriter.ItemEnqueuePositionCalculator.Options;

import static org.junit.Assert.assertEquals;

public class DBWriterTest {

    public static class ItemEnqueuePositionCalculatorTest {

        @RunWith(Parameterized.class)
        public static class IEPCBasicTest {
            @Parameters(name = "{index}: case<{0}>, expected:{1}")
            public static Iterable<Object[]> data() {
                Options optDefault = new Options();
                Options optEnqAtFront = new Options().setEnqueueAtFront(true);

                return Arrays.asList(new Object[][]{
                        {"case default, i.e., add to the end",
                                concat(QUEUE_DEFAULT_IDS, TFI_ID),
                                optDefault, 0, QUEUE_DEFAULT},
                        {"case default (2nd item)",
                                concat(QUEUE_DEFAULT_IDS, TFI_ID),
                                optDefault, 1, QUEUE_DEFAULT},
                        {"case option enqueue at front",
                                concat(TFI_ID, QUEUE_DEFAULT_IDS),
                                optEnqAtFront, 0, QUEUE_DEFAULT},
                        {"case option enqueue at front (2nd item)",
                                list(11L, TFI_ID, 12L, 13L, 14L),
                                optEnqAtFront, 1, QUEUE_DEFAULT},
                        {"case empty queue, option default",
                                list(TFI_ID),
                                optDefault, 0, QUEUE_EMPTY},
                        {"case empty queue, option enqueue at front",
                                list(TFI_ID),
                                optEnqAtFront, 0, QUEUE_EMPTY},
                });
            }

            @Parameter
            public String message;

            @Parameter(1)
            public List<Long> idsExpected;

            @Parameter(2)
            public Options options;

            @Parameter(3)
            public int posAmongAdded; // the position of feed item to be inserted among the list to be inserted.

            @Parameter(4)
            public List<FeedItem> curQueue;


            public static final long TFI_ID = 101;

            /**
             * Add a FeedItem with ID {@link #TFI_ID} with the setup
             */
            @Test
            public void test() {
                ItemEnqueuePositionCalculator calculator = new ItemEnqueuePositionCalculator(options);

                // shallow copy to which the test will add items
                List<FeedItem> queue = new ArrayList<>(curQueue);
                FeedItem tFI = tFI(TFI_ID);
                doAddToQueueAndAssertResult(message,
                        calculator, posAmongAdded, tFI, queue,
                        idsExpected);
            }

        }

        @RunWith(Parameterized.class)
        public static class IEPCKeepInProgressAtFrontTest extends IEPCBasicTest {
            @Parameters(name = "{index}: case<{0}>, expected:{1}")
            public static Iterable<Object[]> data() {
                Options optKeepInProgressAtFront =
                        new Options().setEnqueueAtFront(true).setKeepInProgressAtFront(true);
                // edge case: keep in progress without enabling enqueue at front is meaningless
                Options optKeepInProgressAtFrontWithNoEnqueueAtFront =
                        new Options().setKeepInProgressAtFront(true);

                return Arrays.asList(new Object[][]{
                        {"case option keep in progress at front",
                                list(11L, TFI_ID, 12L, 13L),
                                optKeepInProgressAtFront, 0, QUEUE_FRONT_IN_PROGRESS},
                        {"case option keep in progress at front (2nd item)",
                                list(11L, 12L, TFI_ID, 13L),
                                optKeepInProgressAtFront, 1, QUEUE_FRONT_IN_PROGRESS},
                        {"case option keep in progress at front, front item not in progress",
                                concat(TFI_ID, QUEUE_DEFAULT_IDS),
                                optKeepInProgressAtFront, 0, QUEUE_DEFAULT},
                        {"case option keep in progress at front, front item no media at all",
                                concat(TFI_ID, QUEUE_FRONT_NO_MEDIA_IDS),
                                optKeepInProgressAtFront, 0, QUEUE_FRONT_NO_MEDIA}, // No media should not cause any exception
                        {"case option keep in progress at front, but enqueue at front is disabled",
                                concat(QUEUE_FRONT_IN_PROGRESS_IDS, TFI_ID),
                                optKeepInProgressAtFrontWithNoEnqueueAtFront, 0, QUEUE_FRONT_IN_PROGRESS},
                        {"case empty queue, option keep in progress at front",
                                list(TFI_ID),
                                optKeepInProgressAtFront, 0, QUEUE_EMPTY},
                });
            }

            private static final List<FeedItem> QUEUE_FRONT_IN_PROGRESS = Arrays.asList(tFI(11, 60000), tFI(12), tFI(13));
            private static final List<Long> QUEUE_FRONT_IN_PROGRESS_IDS = toIDs(QUEUE_FRONT_IN_PROGRESS);

            private static final List<FeedItem> QUEUE_FRONT_NO_MEDIA = Arrays.asList(tFINoMedia(11), tFI(12), tFI(13));
            private static final List<Long> QUEUE_FRONT_NO_MEDIA_IDS = toIDs(QUEUE_FRONT_NO_MEDIA);

        }

        @RunWith(Parameterized.class)
        public static class ItemEnqueuePositionCalculatorPreserveDownloadOrderTest {

            @Parameters(name = "{index}: case<{0}>, expected:{1}")
            public static Iterable<Object[]> data() {
                Options optDefault = new Options();
                Options optEnqAtFront = new Options().setEnqueueAtFront(true);

                // Attempts to make test more readable by showing the expected list of ids<commit_msg>test case tweak: preserve download order test, fix test case name (remove the incomplete expected from test case name)<commit_after>package de.danoeh.antennapod.core.storage;

import android.support.annotation.NonNull;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import de.danoeh.antennapod.core.feed.FeedFile;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.FeedMother;
import de.danoeh.antennapod.core.storage.DBWriter.ItemEnqueuePositionCalculator;
import de.danoeh.antennapod.core.storage.DBWriter.ItemEnqueuePositionCalculator.Options;

import static org.junit.Assert.assertEquals;

public class DBWriterTest {

    public static class ItemEnqueuePositionCalculatorTest {

        @RunWith(Parameterized.class)
        public static class IEPCBasicTest {
            @Parameters(name = "{index}: case<{0}>, expected:{1}")
            public static Iterable<Object[]> data() {
                Options optDefault = new Options();
                Options optEnqAtFront = new Options().setEnqueueAtFront(true);

                return Arrays.asList(new Object[][]{
                        {"case default, i.e., add to the end",
                                concat(QUEUE_DEFAULT_IDS, TFI_ID),
                                optDefault, 0, QUEUE_DEFAULT},
                        {"case default (2nd item)",
                                concat(QUEUE_DEFAULT_IDS, TFI_ID),
                                optDefault, 1, QUEUE_DEFAULT},
                        {"case option enqueue at front",
                                concat(TFI_ID, QUEUE_DEFAULT_IDS),
                                optEnqAtFront, 0, QUEUE_DEFAULT},
                        {"case option enqueue at front (2nd item)",
                                list(11L, TFI_ID, 12L, 13L, 14L),
                                optEnqAtFront, 1, QUEUE_DEFAULT},
                        {"case empty queue, option default",
                                list(TFI_ID),
                                optDefault, 0, QUEUE_EMPTY},
                        {"case empty queue, option enqueue at front",
                                list(TFI_ID),
                                optEnqAtFront, 0, QUEUE_EMPTY},
                });
            }

            @Parameter
            public String message;

            @Parameter(1)
            public List<Long> idsExpected;

            @Parameter(2)
            public Options options;

            @Parameter(3)
            public int posAmongAdded; // the position of feed item to be inserted among the list to be inserted.

            @Parameter(4)
            public List<FeedItem> curQueue;


            public static final long TFI_ID = 101;

            /**
             * Add a FeedItem with ID {@link #TFI_ID} with the setup
             */
            @Test
            public void test() {
                ItemEnqueuePositionCalculator calculator = new ItemEnqueuePositionCalculator(options);

                // shallow copy to which the test will add items
                List<FeedItem> queue = new ArrayList<>(curQueue);
                FeedItem tFI = tFI(TFI_ID);
                doAddToQueueAndAssertResult(message,
                        calculator, posAmongAdded, tFI, queue,
                        idsExpected);
            }

        }

        @RunWith(Parameterized.class)
        public static class IEPCKeepInProgressAtFrontTest extends IEPCBasicTest {
            @Parameters(name = "{index}: case<{0}>, expected:{1}")
            public static Iterable<Object[]> data() {
                Options optKeepInProgressAtFront =
                        new Options().setEnqueueAtFront(true).setKeepInProgressAtFront(true);
                // edge case: keep in progress without enabling enqueue at front is meaningless
                Options optKeepInProgressAtFrontWithNoEnqueueAtFront =
                        new Options().setKeepInProgressAtFront(true);

                return Arrays.asList(new Object[][]{
                        {"case option keep in progress at front",
                                list(11L, TFI_ID, 12L, 13L),
                                optKeepInProgressAtFront, 0, QUEUE_FRONT_IN_PROGRESS},
                        {"case option keep in progress at front (2nd item)",
                                list(11L, 12L, TFI_ID, 13L),
                                optKeepInProgressAtFront, 1, QUEUE_FRONT_IN_PROGRESS},
                        {"case option keep in progress at front, front item not in progress",
                                concat(TFI_ID, QUEUE_DEFAULT_IDS),
                                optKeepInProgressAtFront, 0, QUEUE_DEFAULT},
                        {"case option keep in progress at front, front item no media at all",
                                concat(TFI_ID, QUEUE_FRONT_NO_MEDIA_IDS),
                                optKeepInProgressAtFront, 0, QUEUE_FRONT_NO_MEDIA}, // No media should not cause any exception
                        {"case option keep in progress at front, but enqueue at front is disabled",
                                concat(QUEUE_FRONT_IN_PROGRESS_IDS, TFI_ID),
                                optKeepInProgressAtFrontWithNoEnqueueAtFront, 0, QUEUE_FRONT_IN_PROGRESS},
                        {"case empty queue, option keep in progress at front",
                                list(TFI_ID),
                                optKeepInProgressAtFront, 0, QUEUE_EMPTY},
                });
            }

            private static final List<FeedItem> QUEUE_FRONT_IN_PROGRESS = Arrays.asList(tFI(11, 60000), tFI(12), tFI(13));
            private static final List<Long> QUEUE_FRONT_IN_PROGRESS_IDS = toIDs(QUEUE_FRONT_IN_PROGRESS);

            private static final List<FeedItem> QUEUE_FRONT_NO_MEDIA = Arrays.asList(tFINoMedia(11), tFI(12), tFI(13));
            private static final List<Long> QUEUE_FRONT_NO_MEDIA_IDS = toIDs(QUEUE_FRONT_NO_MEDIA);

        }

        @RunWith(Parameterized.class)
        public static class ItemEnqueuePositionCalculatorPreserveDownloadOrderTest {

            @Parameters(name = "{index}: case<{0}>")
            public static Iterable<Object[]> data() {
                Options optDefault = new Options();
                Options optEnqAtFront = new Options().setEnqueueAtFront(true);

                // Attempts to make test more readable by showing the expected list of ids
{'fraction_non_alphanumeric': 0.07897261790538047, 'fraction_numerical': 0.009520997859620637, 'mean_word_length': 1.7686963628933388, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3141488', 'n_tokens_mistral': 3763, 'n_tokens_neox': 3454, 'n_words': 868}