Codebase list mozc / debian/1.13.1651.102-1 dictionary / file / codec_test.cc
debian/1.13.1651.102-1

Tree @debian/1.13.1651.102-1 (Download .tar.gz)

codec_test.cc @debian/1.13.1651.102-1raw · history · blame

// Copyright 2010-2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dictionary/file/codec.h"

#include "base/file_stream.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/util.h"
#include "dictionary/file/codec_interface.h"
#include "dictionary/file/section.h"
#include "testing/base/public/googletest.h"
#include "testing/base/public/gunit.h"

DECLARE_string(test_tmpdir);

namespace mozc {
namespace {

class CodecTest : public ::testing::Test {
 public:
  CodecTest() : test_file_(FLAGS_test_tmpdir + "testfile.txt") {}

 protected:
  virtual void SetUp() {
    DictionaryFileCodecFactory::SetCodec(NULL);
    FileUtil::Unlink(test_file_);
  }

  virtual void TearDown() {
    // Reset to default setting
    DictionaryFileCodecFactory::SetCodec(NULL);
    FileUtil::Unlink(test_file_);
  }

  void AddSection(const DictionaryFileCodecInterface *codec,
                  const string &name,
                  const char *ptr,
                  int len,
                  vector<DictionaryFileSection> *sections) const {
    CHECK(codec);
    CHECK(sections);
    sections->push_back(
        DictionaryFileSection(ptr, len, codec->GetSectionName(name)));
  }

  bool FindSection(const DictionaryFileCodecInterface *codec,
                   const vector<DictionaryFileSection> &sections,
                   const string &name,
                   int *index) const {
    CHECK(codec);
    CHECK(index);
    const string name_find = codec->GetSectionName(name);
    for (size_t i = 0; i < sections.size(); ++i) {
      if (sections[i].name == name_find) {
        *index = i;
        return true;
      }
    }
    return false;
  }

  bool CheckValue(const DictionaryFileSection &section,
                  const string &expected) const {
    const string value = string(section.ptr, section.len);
    return (expected == value);
  }

  const string test_file_;
};

class CodecMock : public DictionaryFileCodecInterface {
 public:
  virtual void WriteSections(const vector<DictionaryFileSection> &sections,
                             ostream *ofs) const {
    const string value = "dummy value";
    ofs->write(value.data(), value.size());
  }

  virtual bool ReadSections(const char *image, int length,
                            vector<DictionaryFileSection> *sections) const {
    sections->push_back(DictionaryFileSection(NULL, 0, "dummy name"));
    return true;
  }

  virtual string GetSectionName(const string &name) const {
    return "dummy section name";
  }
};

TEST_F(CodecTest, FactoryTest) {
  scoped_ptr<CodecMock> codec_mock(new CodecMock);
  DictionaryFileCodecFactory::SetCodec(codec_mock.get());
  const DictionaryFileCodecInterface *codec =
      DictionaryFileCodecFactory::GetCodec();
  EXPECT_TRUE(codec != NULL);
  vector<DictionaryFileSection> sections;
  {
    OutputFileStream ofs;
    ofs.open(test_file_.c_str(), ios_base::out | ios_base::binary);
    codec->WriteSections(sections, &ofs);
  }
  {
    EXPECT_TRUE(FileUtil::FileExists(test_file_));
    InputFileStream ifs;
    ifs.open(test_file_.c_str(), ios_base::in | ios_base::binary);
    ifs.seekg(0, ios::end);
    const int len = ifs.tellg();
    ifs.seekg(0, ios::beg);
    char buf[64];
    ifs.read(buf, len);
    EXPECT_EQ("dummy value", string(buf, len));
  }
  {
    EXPECT_EQ(0, sections.size());
    EXPECT_TRUE(codec->ReadSections(NULL, 0, &sections));
    EXPECT_EQ(1, sections.size());
    EXPECT_EQ("dummy name", sections[0].name);
  }
  {
    EXPECT_EQ("dummy section name", codec->GetSectionName("test"));
  }
}

TEST_F(CodecTest, DefaultTest) {
  const DictionaryFileCodecInterface *codec =
      DictionaryFileCodecFactory::GetCodec();
  EXPECT_TRUE(codec != NULL);
  {
    vector<DictionaryFileSection> write_sections;
    const string value0 = "Value 0 test";
    AddSection(codec, "Section 0", value0.data(), value0.size(),
               &write_sections);
    const string value1 = "Value 1 test test";
    AddSection(codec, "Section 1", value1.data(), value1.size(),
               &write_sections);
    OutputFileStream ofs;
    ofs.open(test_file_.c_str(), ios_base::out | ios_base::binary);
    codec->WriteSections(write_sections, &ofs);
  }
  char buf[1024] = {};  // sections will reference this buffer.
  vector<DictionaryFileSection> sections;
  {
    EXPECT_TRUE(FileUtil::FileExists(test_file_));
    InputFileStream ifs;
    ifs.open(test_file_.c_str(), ios_base::in | ios_base::binary);
    ifs.read(buf, 1024);
    EXPECT_TRUE(codec->ReadSections(buf, 1024, &sections));
  }
  EXPECT_EQ(2, sections.size());
  int index = -1;
  EXPECT_TRUE(FindSection(codec, sections, "Section 0", &index));
  EXPECT_TRUE(CheckValue(sections[index], "Value 0 test"));

  EXPECT_TRUE(FindSection(codec, sections, "Section 1", &index));
  EXPECT_TRUE(CheckValue(sections[index], "Value 1 test test"));
}

TEST_F(CodecTest, CodecTest) {
  scoped_ptr<DictionaryFileCodec> default_codec(
      new DictionaryFileCodec);
  DictionaryFileCodecFactory::SetCodec(default_codec.get());
  const DictionaryFileCodecInterface *codec =
      DictionaryFileCodecFactory::GetCodec();
  EXPECT_TRUE(codec != NULL);
  {
    vector<DictionaryFileSection> write_sections;
    const string value0 = "Value 0 test";
    AddSection(codec, "Section 0", value0.data(), value0.size(),
               &write_sections);
    const string value1 = "Value 1 test test";
    AddSection(codec, "Section 1", value1.data(), value1.size(),
               &write_sections);
    OutputFileStream ofs;
    ofs.open(test_file_.c_str(), ios_base::out | ios_base::binary);
    codec->WriteSections(write_sections, &ofs);
  }
  char buf[1024] = {};  // sections will reference this buffer.
  vector<DictionaryFileSection> sections;
  {
    EXPECT_TRUE(FileUtil::FileExists(test_file_));
    InputFileStream ifs;
    ifs.open(test_file_.c_str(), ios_base::in | ios_base::binary);
    ifs.read(buf, 1024);
    EXPECT_TRUE(codec->ReadSections(buf, 1024, &sections));
  }
  EXPECT_EQ(2, sections.size());
  int index = -1;
  EXPECT_TRUE(FindSection(codec, sections, "Section 0", &index));
  EXPECT_TRUE(CheckValue(sections[index], "Value 0 test"));

  EXPECT_TRUE(FindSection(codec, sections, "Section 1", &index));
  EXPECT_TRUE(CheckValue(sections[index], "Value 1 test test"));
}


}  // namespace
}  // namespace mozc