/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed 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 "type_lookup_table.h"

#include <memory>

#include "base/common_art_test.h"
#include "dex/dex_file-inl.h"
#include "dex/utf-inl.h"
#include "scoped_thread_state_change-inl.h"

namespace art {

using DescriptorClassDefIdxPair = std::pair<const char*, uint32_t>;
class TypeLookupTableTest : public CommonArtTestWithParam<DescriptorClassDefIdxPair> {};

TEST_F(TypeLookupTableTest, CreateLookupTable) {
  std::unique_ptr<const DexFile> dex_file(OpenTestDexFile("Lookup"));
  TypeLookupTable table = TypeLookupTable::Create(*dex_file);
  ASSERT_TRUE(table.Valid());
  ASSERT_NE(nullptr, table.RawData());
  ASSERT_EQ(32U, table.RawDataLength());
}

TEST_P(TypeLookupTableTest, Find) {
  std::unique_ptr<const DexFile> dex_file(OpenTestDexFile("Lookup"));
  TypeLookupTable table(TypeLookupTable::Create(*dex_file));
  ASSERT_TRUE(table.Valid());
  auto pair = GetParam();
  const char* descriptor = pair.first;
  size_t hash = ComputeModifiedUtf8Hash(descriptor);
  uint32_t class_def_idx = table.Lookup(descriptor, hash);
  ASSERT_EQ(pair.second, class_def_idx);
}

INSTANTIATE_TEST_CASE_P(FindNonExistingClassWithoutCollisions,
                        TypeLookupTableTest,
                        testing::Values(DescriptorClassDefIdxPair("LAB;", 1U)));
INSTANTIATE_TEST_CASE_P(FindNonExistingClassWithCollisions,
                        TypeLookupTableTest,
                        testing::Values(DescriptorClassDefIdxPair("LDA;", dex::kDexNoIndex)));
INSTANTIATE_TEST_CASE_P(FindClassNoCollisions,
                        TypeLookupTableTest,
                        testing::Values(DescriptorClassDefIdxPair("LC;", 2U)));
INSTANTIATE_TEST_CASE_P(FindClassWithCollisions,
                        TypeLookupTableTest,
                        testing::Values(DescriptorClassDefIdxPair("LAB;", 1U)));
}  // namespace art
