blob: 815dc00b4ab1bd9b34a04db0877ddbe6f1e776fa [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "chrome/browser/sync_file_system/drive_backend_v1/local_sync_operation_resolver.h"
#include "chrome/browser/sync_file_system/file_change.h"
#include "chrome/browser/sync_file_system/sync_file_type.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace sync_file_system {
namespace {
struct Input {
scoped_ptr<FileChange> remote_file_change;
SyncFileType remote_file_type_in_metadata;
std::string DebugString() const {
std::string change_type =
(remote_file_change == NULL) ? "none"
: remote_file_change->DebugString();
std::ostringstream ss;
ss << "RemoteFileChange: " << change_type
<< ", RemoteFileTypeInMetadata: " << remote_file_type_in_metadata;
return ss.str();
}
Input(FileChange* remote_file_change,
SyncFileType remote_file_type_in_metadata)
: remote_file_change(remote_file_change),
remote_file_type_in_metadata(remote_file_type_in_metadata) {
}
};
template <typename type, size_t array_size>
std::vector<type> CreateList(const type (&inputs)[array_size]) {
return std::vector<type>(inputs, inputs + array_size);
}
ScopedVector<Input> CreateInput() {
SyncFileType dummy_file_type = SYNC_FILE_TYPE_UNKNOWN;
ScopedVector<Input> vector;
vector.push_back(new Input(NULL, SYNC_FILE_TYPE_UNKNOWN));
vector.push_back(new Input(NULL, SYNC_FILE_TYPE_FILE));
vector.push_back(new Input(NULL, SYNC_FILE_TYPE_DIRECTORY));
// When remote_file_change exists, the resolver does not take care of
// remote_file_type_in_metadata.
vector.push_back(new Input(
new FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
SYNC_FILE_TYPE_FILE),
dummy_file_type));
vector.push_back(new Input(
new FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
SYNC_FILE_TYPE_DIRECTORY),
dummy_file_type));
vector.push_back(new Input(
new FileChange(FileChange::FILE_CHANGE_DELETE,
SYNC_FILE_TYPE_FILE),
dummy_file_type));
vector.push_back(new Input(
new FileChange(FileChange::FILE_CHANGE_DELETE,
SYNC_FILE_TYPE_DIRECTORY),
dummy_file_type));
return vector.Pass();
}
std::string DebugString(const ScopedVector<Input>& inputs, int number) {
std::ostringstream ss;
ss << "Case " << number << ": (" << inputs[number]->DebugString() << ")";
return ss.str();
}
} // namespace
class LocalSyncOperationResolverTest : public testing::Test {
public:
LocalSyncOperationResolverTest() {}
protected:
typedef LocalSyncOperationResolver Resolver;
typedef std::vector<SyncOperationType> ExpectedTypes;
private:
DISALLOW_COPY_AND_ASSIGN(LocalSyncOperationResolverTest);
};
TEST_F(LocalSyncOperationResolverTest, ResolveForAddOrUpdateFile) {
const SyncOperationType kExpectedTypes[] = {
SYNC_OPERATION_ADD_FILE,
SYNC_OPERATION_UPDATE_FILE,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_CONFLICT,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_RESOLVE_TO_LOCAL,
SYNC_OPERATION_RESOLVE_TO_LOCAL,
};
ExpectedTypes expected_types = CreateList(kExpectedTypes);
ScopedVector<Input> inputs = CreateInput();
ASSERT_EQ(expected_types.size(), inputs.size());
for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) {
EXPECT_EQ(expected_types[i],
Resolver::ResolveForAddOrUpdateFile(
inputs[i]->remote_file_change.get(),
inputs[i]->remote_file_type_in_metadata))
<< DebugString(inputs, i);
}
}
TEST_F(LocalSyncOperationResolverTest, ResolveForAddOrUpdateFileInConflict) {
const SyncOperationType kExpectedTypes[] = {
SYNC_OPERATION_CONFLICT,
SYNC_OPERATION_CONFLICT,
SYNC_OPERATION_CONFLICT,
SYNC_OPERATION_CONFLICT,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_RESOLVE_TO_LOCAL,
SYNC_OPERATION_RESOLVE_TO_LOCAL,
};
ExpectedTypes expected_types = CreateList(kExpectedTypes);
ScopedVector<Input> inputs = CreateInput();
ASSERT_EQ(expected_types.size(), inputs.size());
for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) {
EXPECT_EQ(expected_types[i],
Resolver::ResolveForAddOrUpdateFileInConflict(
inputs[i]->remote_file_change.get()))
<< DebugString(inputs, i);
}
}
TEST_F(LocalSyncOperationResolverTest, ResolveForAddDirectory) {
const SyncOperationType kExpectedTypes[] = {
SYNC_OPERATION_ADD_DIRECTORY,
SYNC_OPERATION_RESOLVE_TO_LOCAL,
SYNC_OPERATION_NONE,
SYNC_OPERATION_RESOLVE_TO_LOCAL,
SYNC_OPERATION_NONE,
SYNC_OPERATION_ADD_DIRECTORY,
SYNC_OPERATION_RESOLVE_TO_LOCAL,
};
ExpectedTypes expected_types = CreateList(kExpectedTypes);
ScopedVector<Input> inputs = CreateInput();
ASSERT_EQ(expected_types.size(), inputs.size());
for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) {
EXPECT_EQ(expected_types[i],
Resolver::ResolveForAddDirectory(
inputs[i]->remote_file_change.get(),
inputs[i]->remote_file_type_in_metadata))
<< DebugString(inputs, i);
}
}
TEST_F(LocalSyncOperationResolverTest, ResolveForAddDirectoryInConflict) {
EXPECT_EQ(SYNC_OPERATION_RESOLVE_TO_LOCAL,
Resolver::ResolveForAddDirectoryInConflict());
}
TEST_F(LocalSyncOperationResolverTest, ResolveForDelete) {
const SyncOperationType kExpectedTypes[] = {
SYNC_OPERATION_DELETE,
SYNC_OPERATION_DELETE,
SYNC_OPERATION_DELETE,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_DELETE_METADATA,
SYNC_OPERATION_DELETE_METADATA,
};
ExpectedTypes expected_types = CreateList(kExpectedTypes);
ScopedVector<Input> inputs = CreateInput();
ASSERT_EQ(expected_types.size(), inputs.size());
for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) {
EXPECT_EQ(expected_types[i],
Resolver::ResolveForDelete(
inputs[i]->remote_file_change.get(),
inputs[i]->remote_file_type_in_metadata))
<< DebugString(inputs, i);
}
}
TEST_F(LocalSyncOperationResolverTest, ResolveForDeleteInConflict) {
const SyncOperationType kExpectedTypes[] = {
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_RESOLVE_TO_REMOTE,
SYNC_OPERATION_DELETE_METADATA,
SYNC_OPERATION_DELETE_METADATA,
};
ExpectedTypes expected_types = CreateList(kExpectedTypes);
ScopedVector<Input> inputs = CreateInput();
ASSERT_EQ(expected_types.size(), inputs.size());
for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) {
EXPECT_EQ(expected_types[i],
Resolver::ResolveForDeleteInConflict(
inputs[i]->remote_file_change.get()))
<< DebugString(inputs, i);
}
}
} // namespace sync_file_system