package com.raizlabs.android.dbflow.test.sql;

import com.raizlabs.android.dbflow.annotation.Collate;
import com.raizlabs.android.dbflow.sql.language.Condition;
import com.raizlabs.android.dbflow.sql.builder.ConditionQueryBuilder;
import com.raizlabs.android.dbflow.sql.language.ConditionGroup;
import com.raizlabs.android.dbflow.test.FlowTestCase;

import static com.raizlabs.android.dbflow.sql.language.Condition.column;
import static com.raizlabs.android.dbflow.sql.language.NameAlias.columnRaw;

/**
 * Author: andrewgrosner
 * Description: Test our {@link com.raizlabs.android.dbflow.sql.builder.ConditionQueryBuilder} and
 * {@link Condition} classes to ensure they generate what they're supposed to.
 */
public class BuilderTest extends FlowTestCase {

    /**
     * This test will ensure that all column values are converted appropriately
     */
    public void testConditions() {
        ConditionQueryBuilder<ConditionModel> conditionQueryBuilder
                = new ConditionQueryBuilder<>(ConditionModel.class);
        conditionQueryBuilder.addConditions(
                column("number").is(5L),
                column("bytes").is(5),
                column("fraction").is(6.5d));

        assertEquals("`number`=5 AND `bytes`=5 AND `fraction`=6.5", conditionQueryBuilder.getQuery());


        conditionQueryBuilder = new ConditionQueryBuilder<>(ConditionModel.class)
                .addCondition(column(ConditionModel$Table.NUMBER).between(5L).and(10L));
        assertEquals("`number` BETWEEN 5 AND 10", conditionQueryBuilder.getQuery().trim());
    }

    public void testCollate() {
        Condition collate = column(ConditionModel$Table.NAME).is("James").collate(Collate.NOCASE);
        ConditionQueryBuilder<ConditionModel> conditionQueryBuilder = new ConditionQueryBuilder<>(ConditionModel.class);
        collate.appendConditionToQuery(conditionQueryBuilder);

        assertEquals("`name`='James' COLLATE NOCASE", conditionQueryBuilder.getQuery().trim());

    }

    public void testChainingConditions() {
        ConditionQueryBuilder<ConditionModel> conditionQueryBuilder = new ConditionQueryBuilder<>(ConditionModel.class);
        conditionQueryBuilder.addCondition(column(ConditionModel$Table.NAME).is("James").separator("OR"))
                .addCondition(column(ConditionModel$Table.NUMBER).is(6).separator("AND"))
                .addCondition(column(ConditionModel$Table.FRACTION).is(4.5d));
        assertEquals("`name`='James' OR `number`=6 AND `fraction`=4.5", conditionQueryBuilder.getQuery().trim());
    }

    public void testIsOperators() {
        ConditionQueryBuilder<ConditionModel> conditionQueryBuilder = new ConditionQueryBuilder<>(ConditionModel.class);
        conditionQueryBuilder.addCondition(column(ConditionModel$Table.NAME).is("James"))
                .or(column(ConditionModel$Table.FRACTION).isNotNull());
        assertEquals("`name`='James' OR `fraction` IS NOT NULL", conditionQueryBuilder.getQuery().trim());
    }

    public void testInOperators() {
        Condition.In in = column(ConditionModel$Table.NAME).in("Jason", "Ryan", "Michael");
        ConditionQueryBuilder<ConditionModel> conditionQueryBuilder = new ConditionQueryBuilder<>(ConditionModel.class, in);
        assertEquals("`name` IN ('Jason','Ryan','Michael')", conditionQueryBuilder.getQuery().trim());

        Condition.In notIn = column(ConditionModel$Table.NAME).notIn("Jason", "Ryan", "Michael");
        conditionQueryBuilder = new ConditionQueryBuilder<>(ConditionModel.class, notIn);
        assertEquals("`name` NOT IN ('Jason','Ryan','Michael')", conditionQueryBuilder.getQuery().trim());
    }

    public void testCombinedOperations() {
        ConditionGroup combinedCondition = ConditionGroup
                .begin(ConditionGroup
                        .begin(column(columnRaw("A"))).or(column(columnRaw("B"))))
                .and(column(columnRaw("C")));
        ConditionQueryBuilder<ConditionModel> conditionQueryBuilder = new ConditionQueryBuilder<>(ConditionModel.class, combinedCondition);
        assertEquals("((A OR B) AND C)", conditionQueryBuilder.getQuery());
    }

}

@@ -130,32 +130,31 @@
 .dbflow.sql.
-language
+builder
 .Condition;%0A
@@ -151,16 +151,28 @@
 ondition
+QueryBuilder
 ;%0Aimport
@@ -196,39 +196,40 @@
 roid.dbflow.sql.
-builder
+language
 .ConditionQueryB
@@ -218,36 +218,24 @@
 ge.Condition
-QueryBuilder
 ;%0Aimport com
@@ -905,213 +905,111 @@
 tion
-QueryBuilder%3CConditionModel%3E conditionQueryBuilder%0A                = new ConditionQueryBuilder%3C%3E(ConditionModel.class);%0A        conditionQueryBuilder.addConditions(%0A                column(%22
+Group conditionGroup = ConditionGroup.clause()%0A                .and(ConditionModel$Table.
 number
-%22)
 .is(5L)
-,
+)
 %0A   
@@ -1025,30 +1025,46 @@
     
-column(%22
+.and(ConditionModel$Table.
 bytes
-%22)
 .is(5)
-,
+)
 %0A   
@@ -1080,24 +1080,42 @@
     
-column(%22
+.and(ConditionModel$Table.
 fraction
 %22).i
@@ -1110,18 +1110,16 @@
 fraction
-%22)
 .is(6.5d
@@ -1196,36 +1196,29 @@
 %22, condition
-QueryBuilder
+Group
 .getQuery())

tweak test