/*
 * Unit tests for DiaExpression
 */

#include <diacanvas/dia-constraint.h>
#include "unit-test.h"

void setup (void) {}

void teardown (void) {}

TEST_BEGIN (DiaExpression, setup, teardown)

TEST_NEW (dia_expression_free)
{
	DiaExpression *expr = NULL;
        DiaVariable *var = dia_variable_new ();
	gboolean var_destroyed = FALSE;

	TEST_WEAK_REF (var, var_destroyed);

	expr = g_new (DiaExpression, 1);

	expr->len = 1;
	expr->elem[0].variable = g_object_ref (var);
	expr->elem[0].constant = 1.0;

	dia_expression_free (expr);
	TEST (G_OBJECT (var)->ref_count == 1);

	g_object_unref (var);
	TEST (var_destroyed == TRUE);
}

TEST_NEW (dia_expression_add)
{
	DiaExpression *expr = NULL;
        DiaVariable *var1 = dia_variable_new ();
	DiaVariable *var2 = dia_variable_new ();
	gboolean var1_destroyed = FALSE;
	gboolean var2_destroyed = FALSE;

	TEST_WEAK_REF (var1, var1_destroyed);
	TEST_WEAK_REF (var2, var2_destroyed);

	dia_expression_add (&expr, var1, 1.0);
	TEST (expr != NULL);
	TEST (expr->len == 1);
	TEST (expr->elem[0].variable == var1);
	TEST (expr->elem[0].constant == 1.0);

	dia_expression_add (&expr, var2, 2.0);
	TEST (expr != NULL);
	TEST (expr->len == 2);
	TEST (expr->elem[0].variable == var1);
	TEST (expr->elem[0].constant == 1.0);
	TEST (expr->elem[1].variable == var2);
	TEST (expr->elem[1].constant == 2.0);

	g_object_unref (var1);
	g_object_unref (var2);
	TEST (var1_destroyed == FALSE);
	TEST (var2_destroyed == FALSE);

	dia_expression_free (expr);
	TEST (var1_destroyed == TRUE);
	TEST (var2_destroyed == TRUE);
}

TEST_NEW (dia_expression_add_expression)
{
	DiaExpression *expr1 = NULL;
	DiaExpression *expr2 = NULL;
        DiaVariable *var1 = dia_variable_new ();
	DiaVariable *var2 = dia_variable_new ();
	gboolean var1_destroyed = FALSE;
	gboolean var2_destroyed = FALSE;

	TEST_WEAK_REF (var1, var1_destroyed);
	TEST_WEAK_REF (var2, var2_destroyed);

	dia_expression_add (&expr1, var1, 1.0);
	dia_expression_add (&expr1, var2, 1.0);
	TEST (expr1->len == 2);

	dia_expression_add (&expr2, var1, 1.0);
	TEST (expr2->len == 1);

	dia_expression_add_expression (&expr1, expr2);
	TEST (expr1->len == 3);
	TEST (expr1->elem[0].variable == var1);
	TEST (expr1->elem[1].variable == var2);
	TEST (expr1->elem[2].variable == var1);

	TEST (G_OBJECT (var1)->ref_count == 4);
	TEST (G_OBJECT (var2)->ref_count == 2);

	g_object_unref (var1);
	g_object_unref (var2);
	TEST (var1_destroyed == FALSE);
	TEST (var2_destroyed == FALSE);

	dia_expression_free (expr2);
	TEST (var1_destroyed == FALSE);
	TEST (var2_destroyed == FALSE);
	TEST (G_OBJECT (var1)->ref_count == 2);
	TEST (G_OBJECT (var2)->ref_count == 1);

	dia_expression_free (expr1);
	TEST (var1_destroyed == TRUE);
	TEST (var2_destroyed == TRUE);
}


TEST_NEW (dia_expression_times)
{
	DiaExpression *expr = NULL;
        DiaVariable *var1 = dia_variable_new ();
	DiaVariable *var2 = dia_variable_new ();
	gboolean var1_destroyed = FALSE;
	gboolean var2_destroyed = FALSE;

	TEST_WEAK_REF (var1, var1_destroyed);
	TEST_WEAK_REF (var2, var2_destroyed);

	
	dia_expression_add (&expr, var1, 1.0);
	dia_expression_add (&expr, var2, 2.0);

	dia_expression_times (expr, 3.0);
	TEST (expr->elem[0].constant == 3.0);
	TEST (expr->elem[1].constant == 6.0);

	dia_expression_free (expr);
	g_object_unref (var1);
	g_object_unref (var2);
	TEST (var1_destroyed == TRUE);
	TEST (var2_destroyed == TRUE);
}

TEST_END ()
