/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 * 
 * testExpressionSerializer.cpp
 *
 *  Created on: Jan 4, 2016
 *      Author: pgess <v.melnychenko@xreate.org>
 */

#include "aux/serialization/expressionserializer.h"
#include "serialization.h"
#include "ast.h"
#include "gtest/gtest.h"

using namespace xreate;
using namespace std;

TEST(ExpressionSerializer, pack1){
	PackedExpression x;

	x << std::make_pair(0xA1, 0x100);
	size_t* storage = reinterpret_cast<size_t*> (*x);
	ASSERT_EQ(0xA100000000000000, *storage);

	x << std::make_pair(0x23456, 0x100000);
	ASSERT_EQ(0xA123456000000000, *storage);

	x << std::make_pair(0x7654321, 0x10000000);
	ASSERT_EQ(0xA123456765432100, *storage);


	x << std::make_pair(0xABBA, 0x10000);
	storage = reinterpret_cast<size_t*> (*x);
	ASSERT_EQ(0xA1234567654321AB, *storage);
	ASSERT_EQ(0xBA00000000000000, *(storage+1));
}

TEST(ExpressionSerializer, serialize1){
	Expression a(Operator::CALL, {Expression(string("a")), Expression(string("a"))});
	Expression b(Operator::CALL, {Expression(string("a")), Expression(string("b"))});

	ExpressionSerializer serializer(vector<Expression>{a, b});

	PackedExpression packA = serializer.getId(a);
	PackedExpression packB = serializer.getId(b);
	PackedExpression packA2 = serializer.getId(a);

	ASSERT_EQ(packA, packA2);
	ASSERT_NE(packA, packB);
}

TEST(ExpressionSerializer, serialize2){
	Expression a(Operator::CALL, {Expression(string("a")), Expression(string("a"))});
	Expression b(Operator::CALL, {Expression(string("a")), Expression(string("b"))});
	Expression c(Atom<Identifier_t>("c"));

	typedef ExpressionSerialization<RequirementIntegralCode>::Serializer Serializer;
	Serializer serializer(vector<Expression>{a, b});

	ASSERT_EQ(2, serializer.size());
	ASSERT_EQ(1, serializer.count(a));
	ASSERT_EQ(1, serializer.count(b));
	ASSERT_EQ(0, serializer.count(c));

	Serializer serializer2(move(serializer));
	ASSERT_EQ(1, serializer2.count(a));
}
