/* $Id$
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include "serialization/EtchValidatorString.h"
#include "capu/util/SmartPointer.h"
#include "common/EtchInt32.h"
#include "support/EtchRuntime.h"

class EtchValidatorStringTest
  : public ::testing::Test {
protected:
  virtual void SetUp() {
    mRuntime = new EtchRuntime();
    mRuntime->start();
  }

  virtual void TearDown() {
    mRuntime->shutdown();
    delete mRuntime;
    mRuntime = NULL;
  }

  EtchRuntime* mRuntime;
};

TEST_F(EtchValidatorStringTest, createTest) {
  capu::SmartPointer<EtchValidatorString> ptr = NULL;

  capu::SmartPointer<EtchValidator> val;
  EXPECT_TRUE(EtchValidatorString::Get(mRuntime, 0, val) == ETCH_OK);
  ptr = capu::smartpointer_cast<EtchValidatorString>(val);

  EXPECT_TRUE(ptr->getExpectedType()->equals(EtchString::TYPE()));
  EXPECT_TRUE(ptr->getNDims() == 0);

  EtchObjectType type1(EOTID_STRING, NULL);
  EtchObjectType type2(EOTID_NATIVE_ARRAY, &type1);
  EXPECT_TRUE(EtchValidatorString::Get(mRuntime, 2, val) == ETCH_OK);
  ptr = capu::smartpointer_cast<EtchValidatorString>(val);
  EXPECT_TRUE(ptr->getExpectedType()->equals(&type2));
  EXPECT_TRUE(ptr->getNDims() == 2);

}

TEST_F(EtchValidatorStringTest, validateTest) {
  capu::SmartPointer<EtchObject> str = NULL;
  capu::SmartPointer<EtchObject> integer = new EtchInt32(4);
  capu::SmartPointer<EtchObject> str2 = new EtchString("hello");
  capu::SmartPointer<EtchValidator> ptr = NULL;
  EXPECT_TRUE(EtchValidatorString::Get(mRuntime, 0, ptr) == ETCH_OK);
  EXPECT_TRUE(((EtchTypeValidator*) ptr.get())->getNDims() == 0);
  EXPECT_FALSE(ptr->validate(str));
  EXPECT_FALSE(ptr->validate(integer));
  EXPECT_TRUE(ptr->validate(str2));
}

TEST_F(EtchValidatorStringTest, validateValueTest) {
  capu::SmartPointer<EtchObject> str = NULL;
  capu::SmartPointer<EtchObject> result;
  capu::SmartPointer<EtchObject> integer = new EtchInt32(4);
  capu::SmartPointer<EtchObject> str2 = new EtchString("hello");
  capu::SmartPointer<EtchValidator> ptr = NULL;
  EXPECT_TRUE(EtchValidatorString::Get(mRuntime, 0, ptr) == ETCH_OK);
  EXPECT_TRUE(ptr->validateValue(str, result) == ETCH_ERROR);
  EXPECT_TRUE(ptr->validateValue(integer, result) == ETCH_ERROR);
  EXPECT_TRUE(ptr->validateValue(str2, result) == ETCH_OK);
  EXPECT_TRUE(((EtchString*) result.get())->equals((EtchString*) str2.get()));
}

TEST_F(EtchValidatorStringTest, elementValidatorTest) {
  capu::SmartPointer<EtchValidator> ptr = NULL;
  EXPECT_TRUE(EtchValidatorString::Get(mRuntime, 1, ptr) == ETCH_OK);
  capu::SmartPointer<EtchValidator> elementValidator;
  ptr->getElementValidator(elementValidator);

  capu::SmartPointer<EtchObject> str = NULL;
  capu::SmartPointer<EtchObject> integer = new EtchInt32(4);
  capu::SmartPointer<EtchObject> str2 = new EtchString("hello");

  EXPECT_FALSE(elementValidator->validate(str));
  EXPECT_FALSE(elementValidator->validate(integer));
  EXPECT_TRUE(elementValidator->validate(str2));
}
