package org.lenskit.specs.eval;

import org.junit.Before;
import org.junit.Test;
import org.lenskit.specs.data.PackedDataSourceSpec;
import org.lenskit.specs.data.PrefDomainSpec;
import org.lenskit.specs.data.TextDataSourceSpec;

import java.nio.file.Paths;
import java.util.List;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

public class CrossfoldSpecTest {
    TextDataSourceSpec input;

    @Before
    public void createDataSource() {
        input = new TextDataSourceSpec();
        input.setFile(Paths.get("ratings.csv"));
        input.setName("TestData");
    }

    @Test
    public void testDefaults() {
        CrossfoldSpec spec = new CrossfoldSpec();
        spec.setName("TestData");
        spec.setSource(input);
        spec.setOutputDir(Paths.get("crossfold.out"));

        assertThat(spec.getPartitionCount(), equalTo(5));
        assertThat(spec.getOutputFormat(), equalTo(OutputFormat.CSV));
        assertThat(spec.getOutputDir(), equalTo(Paths.get("crossfold.out")));
        assertThat(spec.getIncludeTimestamps(), equalTo(true));
        assertThat(spec.getMethod(), equalTo(CrossfoldMethod.PARTITION_USERS));
        assertThat(spec.getUserPartitionMethod(),
                   instanceOf(PartitionMethodSpec.Holdout.class));
        PartitionMethodSpec.Holdout holdout = (PartitionMethodSpec.Holdout) spec.getUserPartitionMethod();
        assertThat(holdout.getCount(), equalTo(10));
        assertThat(holdout.getOrder(), equalTo("random"));
    }

    @Test
    public void testBasicDataSets() {
        CrossfoldSpec spec = new CrossfoldSpec();
        spec.setName("TestData");
        spec.setSource(input);
        input.setDomain(PrefDomainSpec.fromString("[1,5]/1.0"));
        spec.setOutputDir(Paths.get("crossfold.out"));
        List<DataSetSpec> sets = spec.getDataSets();
        assertThat(sets, hasSize(5));
        for (int i = 0; i < 5; i++) {
            DataSetSpec set = sets.get(i);
            assertThat(set.getName(), equalTo("TestData." + i+1));
            assertThat(set.getAttributes(), hasEntry("DataSet", (Object) "TestData"));
            assertThat(set.getAttributes(), hasEntry("Partition", (Object) (i+1)));

            assertThat(set.getTrainSource(), instanceOf(TextDataSourceSpec.class));
            TextDataSourceSpec tds = (TextDataSourceSpec) set.getTrainSource();
            assertThat(tds.getFile(), equalTo(spec.getOutputDir().resolve(String.format("part%02d.train.csv", i+1))));
            assertThat(tds.getDomain(),
                       equalTo(PrefDomainSpec.fromString("[1,5]/1.0")));
            assertThat(tds.getDelimiter(), equalTo(","));

            assertThat(set.getTestSource(), instanceOf(TextDataSourceSpec.class));
            tds = (TextDataSourceSpec) set.getTestSource();
            assertThat(tds.getFile(), equalTo(spec.getOutputDir().resolve(String.format("part%02d.test.csv", i+1))));
            assertThat(tds.getDomain(),
                       equalTo(PrefDomainSpec.fromString("[1,5]/1.0")));
            assertThat(tds.getDelimiter(), equalTo(","));
        }
    }

    @Test
    public void testPackDataSets() {
        CrossfoldSpec spec = new CrossfoldSpec();
        spec.setName("TestData");
        spec.setSource(input);
        input.setDomain(PrefDomainSpec.fromString("[1,5]/1.0"));
        spec.setOutputDir(Paths.get("crossfold.out"));
        spec.setOutputFormat(OutputFormat.PACK);
        List<DataSetSpec> sets = spec.getDataSets();
        assertThat(sets, hasSize(5));
        for (int i = 0; i < 5; i++) {
            DataSetSpec set = sets.get(i);
            assertThat(set.getName(), equalTo("TestData." + i+1));
            assertThat(set.getAttributes(), hasEntry("DataSet", (Object) "TestData"));
            assertThat(set.getAttributes(), hasEntry("Partition", (Object) (i+1)));

            assertThat(set.getTrainSource(), instanceOf(PackedDataSourceSpec.class));
            PackedDataSourceSpec tds = (PackedDataSourceSpec) set.getTrainSource();
            assertThat(tds.getFile(), equalTo(spec.getOutputDir().resolve(String.format("part%02d.train.pack", i+1))));
            assertThat(tds.getDomain(),
                       equalTo(PrefDomainSpec.fromString("[1,5]/1.0")));

            assertThat(set.getTestSource(), instanceOf(PackedDataSourceSpec.class));
            tds = (PackedDataSourceSpec) set.getTestSource();
            assertThat(tds.getFile(), equalTo(spec.getOutputDir().resolve(String.format("part%02d.test.pack", i+1))));
            assertThat(tds.getDomain(),
                       equalTo(PrefDomainSpec.fromString("[1,5]/1.0")));
        }
    }
}

@@ -1,12 +1,1005 @@
+/*%0A * LensKit, an open source recommender systems toolkit.%0A * Copyright 2010-2014 LensKit Contributors.  See CONTRIBUTORS.md.%0A * Work on LensKit has been funded by the National Science Foundation under%0A * grants IIS 05-34939, 08-08692, 08-12148, and 10-17697.%0A *%0A * This program is free software; you can redistribute it and/or modify%0A * it under the terms of the GNU Lesser General Public License as%0A * published by the Free Software Foundation; either version 2.1 of the%0A * License, or (at your option) any later version.%0A *%0A * This program is distributed in the hope that it will be useful, but WITHOUT%0A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS%0A * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more%0A * details.%0A *%0A * You should have received a copy of the GNU General Public License along with%0A * this program; if not, write to the Free Software Foundation, Inc., 51%0A * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.%0A */%0A
 package org.

add missing license header