/**
     * Test StringSchemaItem with max length
     **/
    TEST(test_item_with_max_length, test_StringSchemaItemTest)
    {
        using namespace NsSmartDeviceLink::NsSmartObjects;
        SmartObject obj;

        utils::SharedPtr<CStringSchemaItem> item = CStringSchemaItem::create(
            TSchemaItemParameter<size_t>(0),
            TSchemaItemParameter<size_t>(25),
            TSchemaItemParameter<std::string>("Default string"));

        //Object - valid string
        obj = "New valid string";
        ASSERT_EQ(std::string("New valid string"), obj.asString());

        int resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
        bool resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj.asString());

        //Object - too long string
        obj = "New very very loooooong string";
        ASSERT_EQ(std::string("New very very loooooong string"), obj.asString());

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OUT_OF_RANGE, resultType);

        resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj.asString());
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
    }
    /**
     * Test StringSchemaItem with default value
     *
     * Create SchemaItem with default value. Method setDefaultValue should return true,
     * String SmartObject should contain default value.
     * Not string SmartObject should converted to StringObject and setted up by the default value.
     **/
    TEST(test_item_with_default_value, test_StringSchemaItemTest)
    {
        using namespace NsSmartDeviceLink::NsSmartObjects;
        SmartObject obj;

        utils::SharedPtr<CStringSchemaItem> item = CStringSchemaItem::create(
            TSchemaItemParameter<size_t>(),
            TSchemaItemParameter<size_t>(),
            TSchemaItemParameter<std::string>("Default string")); // Default value, no max length

        //Object - valid string
        obj = "New valid string";
        ASSERT_EQ(std::string("New valid string"), obj.asString());

        int resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
        bool resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj.asString());

        //Obj - bool
        obj = true;

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);
        resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj.asString());

        //Object - number
        obj = 3.1415926;

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
        EXPECT_EQ(std::string("Default string"), obj.asString());
    }
    /**
     * Test EnumSchemaItem with default value
     *
     * Create SchemaItem without default value. Method setDefaultValue should return false,
     * SmartObject should contain previous value.
     **/
    TEST_F(EnumSchemaItemTest, test_item_without_default_value)
    {
        SmartObject obj;

        ISchemaItemPtr item = TEnumSchemaItem<TestType::eType>::create(testEnum,
            TSchemaItemParameter<TestType::eType>());

        //Object - valid enum
        obj = TestType::BLUETOOTH_OFF;
        int resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
        bool resDefault = item->setDefaultValue(obj);
        EXPECT_FALSE(resDefault);
        EXPECT_EQ(TestType::BLUETOOTH_OFF, obj.asInt());

        //Obj - bool
        obj = true;

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);
        resDefault = item->setDefaultValue(obj);
        EXPECT_FALSE(resDefault);
        EXPECT_TRUE(obj.asBool());

        //Object - number
        obj = 3.1415926;

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        resDefault = item->setDefaultValue(obj);
        EXPECT_FALSE(resDefault);
        EXPECT_EQ(3.1415926, obj.asDouble());

        //Object - string
        obj = "Some string";
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        resDefault = item->setDefaultValue(obj);
        EXPECT_FALSE(resDefault);
        EXPECT_EQ(std::string("Some string"), obj.asString());

        //Object - int in range of enum
        obj = 6;
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);

        //Object - int out of enum range
        obj = 15;
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OUT_OF_RANGE, resultType);
    }
    /**
     * Test apply and unapply EnumSchemaItem
     **/
    TEST_F(EnumSchemaItemTest, test_apply_unapply_schema)
    {
        SmartObject obj;

        ISchemaItemPtr item = TEnumSchemaItem<TestType::eType>::create(testEnum,
            TSchemaItemParameter<TestType::eType>(TestType::FACTORY_DEFAULTS));

        //Object - valid enum
        obj = TestType::BLUETOOTH_OFF;
        int resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
        bool resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(TestType::FACTORY_DEFAULTS, obj.asInt());

        item->unapplySchema(obj);
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);
        EXPECT_EQ(std::string("FACTORY_DEFAULTS"), obj.asString());

        item->applySchema(obj);
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
        EXPECT_EQ(TestType::FACTORY_DEFAULTS, obj.asInt());

        obj = "TOO_MANY_REQUESTS";
        item->applySchema(obj);
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
        EXPECT_EQ(TestType::TOO_MANY_REQUESTS, obj.asInt());

        obj = "ENOUGH_REQUESTS";
        item->applySchema(obj);
        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);
        EXPECT_EQ(std::string("ENOUGH_REQUESTS"), obj.asString());
    }
    TEST(test_array_validate, test_StringSchemaItemTest)
    {
        using namespace NsSmartDeviceLink::NsSmartObjects;
        SmartObject obj;

        utils::SharedPtr<CStringSchemaItem> item = CStringSchemaItem::create(
            TSchemaItemParameter<size_t>(0),
            TSchemaItemParameter<size_t>(25),
            TSchemaItemParameter<std::string>("Default string"));

        obj[0] = "New valid string";
        obj[1] = "New very very loooooong string";
        obj[2] = true;
        obj[3] = 3.14;
        obj[4] = "New valid string";

        int resultType = item->validate(obj[0]);
        EXPECT_EQ(Errors::OK, resultType);

        resultType = item->validate(obj[1]);
        EXPECT_EQ(Errors::OUT_OF_RANGE, resultType);

        resultType = item->validate(obj[2]);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        resultType = item->validate(obj[3]);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        resultType = item->validate(obj[4]);
        EXPECT_EQ(Errors::OK, resultType);

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        bool resDefault = item->setDefaultValue(obj[0]);
        EXPECT_TRUE(resDefault);
        resDefault = item->setDefaultValue(obj[2]);
        EXPECT_TRUE(resDefault);
        resDefault = item->setDefaultValue(obj[4]);
        EXPECT_TRUE(resDefault);

        //Set default value for non-initialized element
        resDefault = item->setDefaultValue(obj[5]);
        EXPECT_TRUE(resDefault);

        EXPECT_EQ(std::string("Default string"), obj[0].asString());
        EXPECT_EQ(std::string("Default string"), obj[2].asString());
        EXPECT_EQ(std::string("Default string"), obj[4].asString());
        EXPECT_EQ(std::string("Default string"), obj[5].asString());

        resultType = item->validate(obj[0]);
        EXPECT_EQ(Errors::OK, resultType);
        resultType = item->validate(obj[1]);
        EXPECT_EQ(Errors::OUT_OF_RANGE, resultType);
        resultType = item->validate(obj[2]);
        EXPECT_EQ(Errors::OK, resultType);
        resultType = item->validate(obj[3]);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);
        resultType = item->validate(obj[4]);
        EXPECT_EQ(Errors::OK, resultType);
        resultType = item->validate(obj[5]);
        EXPECT_EQ(Errors::OK, resultType);

        resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj.asString());

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);    }
    TEST(test_map_validate, test_StringSchemaItemTest)
    {
        using namespace NsSmartDeviceLink::NsSmartObjects;
        SmartObject obj;

        utils::SharedPtr<CStringSchemaItem> item = CStringSchemaItem::create(
            TSchemaItemParameter<size_t>(0),
            TSchemaItemParameter<size_t>(25),
            TSchemaItemParameter<std::string>("Default string"));

        obj["str"] = "New valid string";
        obj["long"] = "New very very loooooong string";
        obj["bool"] = true;
        obj["num"] = 3.14;

        int resultType = item->validate(obj["str"]);
        EXPECT_EQ(Errors::OK, resultType);

        resultType = item->validate(obj["long"]);
        EXPECT_EQ(Errors::OUT_OF_RANGE, resultType);

        resultType = item->validate(obj["bool"]);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        resultType = item->validate(obj["num"]);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::INVALID_VALUE, resultType);

        bool resDefault = item->setDefaultValue(obj["str"]);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj["str"].asString());

        resDefault = item->setDefaultValue(obj["bool"]);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj["bool"].asString());

        resDefault = item->setDefaultValue(obj["num"]);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj["num"].asString());

        resultType = item->validate(obj["str"]);
        EXPECT_EQ(Errors::OK, resultType);

        resultType = item->validate(obj["long"]);
        EXPECT_EQ(Errors::OUT_OF_RANGE, resultType);

        resultType = item->validate(obj["bool"]);
        EXPECT_EQ(Errors::OK, resultType);

        resultType = item->validate(obj["num"]);
        EXPECT_EQ(Errors::OK, resultType);

        resDefault = item->setDefaultValue(obj);
        EXPECT_TRUE(resDefault);
        EXPECT_EQ(std::string("Default string"), obj.asString());

        resultType = item->validate(obj);
        EXPECT_EQ(Errors::OK, resultType);
    }