package de.duehl.basics.io.textfile.data;

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;

import de.duehl.basics.collections.CollectionsHelper;

public class DefinitionsTest {

    @Test
    public void emptyDefinitionsHasSize0() {
        Definitions definitions = new Definitions();
        assertEquals(0, definitions.size());
    }

    @Test
    public void addThreeDefinitionsHasSize3() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertEquals(3, definitions.size());
    }

    @Test
    public void addThreeDefinitionsHasSize3ViaListAdd() {
        List<Definition> list = CollectionsHelper.buildListFrom(
                new Definition("a", "Apfel"),
                new Definition("b", "Birne"),
                new Definition("o", "orange")
                );
        Definitions definitions = new Definitions();
        for (Definition definition : list) {
            definitions.add(definition);
        }
        assertEquals(3, definitions.size());
    }

    @Test (expected = RuntimeException.class)
    public void addFailes() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        definitions.add(new Definition("a", "Zitrone"));
    }

    @Test
    public void Iteration() {
        List<Definition> list = CollectionsHelper.buildListFrom(
                new Definition("a", "Apfel"),
                new Definition("b", "Birne"),
                new Definition("o", "orange")
                );
        Definitions definitions = new Definitions();
        for (Definition definition : list) {
            definitions.add(definition);
        }

        for (Definition definition : definitions) {
            assertTrue(list.contains(definition));
        }
    }

    @Test
    public void containsKeySlowViaDefiniton() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertTrue(definitions.containsKeySlow(new Definition("a", "Zitrone")));
    }

    @Test
    public void containsKeySlowViaDefinitonFalse() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertFalse(definitions.containsKeySlow(new Definition("d", "Apfel")));
    }

    @Test
    public void containsKeySlowViaKey() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertTrue(definitions.containsKeySlow("a"));
    }

    @Test
    public void containsKeySlowViaKeyFalse() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertFalse(definitions.containsKeySlow("d"));
    }

    @Test
    public void containsKeyViaDefiniton() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertTrue(definitions.containsKey(new Definition("a", "Zitrone")));
    }

    @Test
    public void containsKeyViaDefinitonFalse() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertFalse(definitions.containsKey(new Definition("d", "Apfel")));
    }

    @Test
    public void containsKeyViaKey() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertTrue(definitions.containsKey("a"));
    }

    @Test
    public void containsKeyViaKeyFalse() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        assertFalse(definitions.containsKey("d"));
    }

    @Test
    public void getValueByKey() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        String actual = definitions.getValueByKey("b");
        String expected = "Birne";
        assertEquals(expected, actual);
    }

    @Test (expected = RuntimeException.class)
    public void getValueByKeyFailes() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        definitions.getValueByKey("c");
    }

    @Test
    public void toStringTest() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        String actual = definitions.toString();
        String expected = "Definitions : [a = Apfel, b = Birne, o = orange]";
        assertEquals(expected, actual);
    }

    @Test
    public void toStringTestEmpty() {
        Definitions definitions = new Definitions();
        String actual = definitions.toString();
        String expected = "Definitions : []";
        assertEquals(expected, actual);
    }

    @Test
    public void getKeys() {
        Definitions definitions = new Definitions();
        definitions.add(new Definition("a", "Apfel"));
        definitions.add(new Definition("b", "Birne"));
        definitions.add(new Definition("o", "orange"));
        List<String> keys = definitions.getKeys();
        assertEquals(3, keys.size());
        assertEquals("a", keys.get(0));
        assertEquals("b", keys.get(1));
        assertEquals("o", keys.get(2));
    }

}
