blob: 3b4c962b84bbaf98c7c8cac124feadc89b7a1e00 [file] [log] [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