// ============================================================================
//
// Copyright (C) 2006-2014 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package org.talend.dataprep.transformation.api.action.metadata.math;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.talend.dataprep.api.dataset.ColumnMetadata.Builder.column;
import static org.talend.dataprep.transformation.api.action.metadata.ActionMetadataTestUtils.getColumn;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;
import org.talend.dataprep.api.dataset.ColumnMetadata;
import org.talend.dataprep.api.dataset.DataSetRow;
import org.talend.dataprep.api.type.Type;
import org.talend.dataprep.transformation.api.action.context.TransformationContext;
import org.talend.dataprep.transformation.api.action.metadata.ActionMetadataTestUtils;
import org.talend.dataprep.transformation.api.action.metadata.category.ActionCategory;

/**
 * Test class for Ceil action. Creates one consumer, and test it.
 *
 * @see Ceil
 */
public class CeilTest {

    /** The action ton test. */
    private Ceil action;

    private Map<String, String> parameters;

    @Before
    public void init() throws IOException {
        action = new Ceil();

        parameters = ActionMetadataTestUtils.parseParameters( //
                action, //
                CeilTest.class.getResourceAsStream("ceilAction.json"));
    }

    @Test
    public void testAdapt() throws Exception {
        assertThat(action.adapt(null), is(action));
        ColumnMetadata column = column().name("myColumn").id(0).type(Type.STRING).build();
        assertThat(action.adapt(column), is(action));
    }

    @Test
    public void testCategory() throws Exception {
        assertThat(action.getCategory(), is(ActionCategory.MATH.getDisplayName()));
    }

    public void testCommon(String input, String expected) {
        // given
        final Map<String, String> values = new HashMap<>();
        values.put("aNumber", input);
        final DataSetRow row = new DataSetRow(values);

        // when
        action.applyOnColumn(row, new TransformationContext(), parameters, "aNumber");

        // then
        assertEquals(expected, row.get("aNumber"));
    }

    @Test
    public void testPositive() {
        testCommon("5.0", "5");
        testCommon("5.1", "6");
        testCommon("5.5", "6");
        testCommon("5.8", "6");
    }

    @Test
    public void testNegative() {
        testCommon("-5.0", "-5");
        testCommon("-5.4", "-5");
        testCommon("-5.6", "-5");
    }

    @Test
    public void test_huge_number() {
        testCommon("1234567890.1", "1234567891");
        testCommon("891234567897.9", "891234567898");
        testCommon("891234567899.9", "891234567900");
        testCommon("999999999999.9", "1000000000000");
    }

    @Test
    public void testInteger() {
        testCommon("5", "5");
        testCommon("-5", "-5");
    }

    @Test
    public void testString() {
        testCommon("tagada", "tagada");
        testCommon("", "");
        testCommon("null", "null");
    }

    @Test
    public void should_accept_column() {
        assertTrue(action.acceptColumn(getColumn(Type.NUMERIC)));
        assertTrue(action.acceptColumn(getColumn(Type.INTEGER)));
        assertTrue(action.acceptColumn(getColumn(Type.DOUBLE)));
        assertTrue(action.acceptColumn(getColumn(Type.FLOAT)));
    }

    @Test
    public void should_not_accept_column() {
        assertFalse(action.acceptColumn(getColumn(Type.STRING)));
        assertFalse(action.acceptColumn(getColumn(Type.DATE)));
        assertFalse(action.acceptColumn(getColumn(Type.BOOLEAN)));
    }
}

@@ -2637,16 +2637,17 @@
 tEquals(
+ 
 expected
@@ -2656,16 +2656,17 @@
 row.get(
+ 
 %22aNumber
@@ -2666,17 +2666,19 @@
 aNumber%22
-)
+ ) 
 );%0A    %7D
@@ -2741,16 +2741,17 @@
 tCommon(
+ 
 %225.0%22, %22
@@ -2748,24 +2748,25 @@
 ( %225.0%22, %225%22
+ 
 );%0A        t
@@ -2807,16 +2807,17 @@
 tCommon(
+ 
 %225.5%22, %22
@@ -2814,24 +2814,25 @@
 ( %225.5%22, %226%22
+ 
 );%0A        t
@@ -2841,16 +2841,17 @@
 tCommon(
+ 
 %225.8%22, %22
@@ -2848,24 +2848,25 @@
 ( %225.8%22, %226%22
+ 
 );%0A    %7D%0A%0A  
@@ -3274,32 +3274,316 @@
 00000%22);%0A    %7D%0A%0A
+%0A    @Test%0A    public void test_huge_number_negative() %7B%0A        testCommon(%22-1234567890.1%22, %22-1234567890%22);%0A        testCommon(%22-891234567897.9%22, %22-891234567897%22);%0A        testCommon(%22-891234567899.9%22, %22-891234567899%22);%0A        testCommon(%22-999999999999.9%22, %22-999999999999%22);%0A    %7D%0A%0A
     @Test%0A    pu

improve Ceil test for huge number with negative values.