1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/invalidation/object_id_invalidation_map_test_util.h"
6
7#include <algorithm>
8
9#include "base/basictypes.h"
10
11namespace syncer {
12
13using ::testing::MakeMatcher;
14using ::testing::MatchResultListener;
15using ::testing::Matcher;
16using ::testing::MatcherInterface;
17using ::testing::PrintToString;
18
19namespace {
20
21class ObjectIdInvalidationMapEqMatcher
22    : public MatcherInterface<const ObjectIdInvalidationMap&> {
23 public:
24  explicit ObjectIdInvalidationMapEqMatcher(
25      const ObjectIdInvalidationMap& expected);
26
27  virtual bool MatchAndExplain(const ObjectIdInvalidationMap& lhs,
28                               MatchResultListener* listener) const;
29  virtual void DescribeTo(::std::ostream* os) const;
30  virtual void DescribeNegationTo(::std::ostream* os) const;
31
32 private:
33  const ObjectIdInvalidationMap expected_;
34
35  DISALLOW_COPY_AND_ASSIGN(ObjectIdInvalidationMapEqMatcher);
36};
37
38ObjectIdInvalidationMapEqMatcher::ObjectIdInvalidationMapEqMatcher(
39    const ObjectIdInvalidationMap& expected) : expected_(expected) {
40}
41
42struct InvalidationEqPredicate {
43  InvalidationEqPredicate(const Invalidation& inv1)
44      : inv1_(inv1) { }
45
46  bool operator()(const Invalidation& inv2) {
47    return inv1_.Equals(inv2);
48  }
49
50  const Invalidation& inv1_;
51};
52
53bool ObjectIdInvalidationMapEqMatcher::MatchAndExplain(
54    const ObjectIdInvalidationMap& actual,
55    MatchResultListener* listener) const {
56
57  std::vector<syncer::Invalidation> expected_invalidations;
58  std::vector<syncer::Invalidation> actual_invalidations;
59
60  expected_.GetAllInvalidations(&expected_invalidations);
61  actual.GetAllInvalidations(&actual_invalidations);
62
63  std::vector<syncer::Invalidation> expected_only;
64  std::vector<syncer::Invalidation> actual_only;
65
66  for (std::vector<syncer::Invalidation>::iterator it =
67       expected_invalidations.begin();
68       it != expected_invalidations.end(); ++it) {
69    if (std::find_if(actual_invalidations.begin(),
70                     actual_invalidations.end(),
71                     InvalidationEqPredicate(*it))
72        == actual_invalidations.end()) {
73      expected_only.push_back(*it);
74    }
75  }
76
77  for (std::vector<syncer::Invalidation>::iterator it =
78       actual_invalidations.begin();
79       it != actual_invalidations.end(); ++it) {
80    if (std::find_if(expected_invalidations.begin(),
81                     expected_invalidations.end(),
82                     InvalidationEqPredicate(*it))
83        == expected_invalidations.end()) {
84      actual_only.push_back(*it);
85    }
86  }
87
88  if (expected_only.empty() && actual_only.empty())
89    return true;
90
91  bool printed_header = false;
92  if (!actual_only.empty()) {
93    *listener << " which has these unexpected elements: "
94              << PrintToString(actual_only);
95    printed_header = true;
96  }
97
98  if (!expected_only.empty()) {
99    *listener << (printed_header ? ",\nand" : "which")
100              << " doesn't have these expected elements: "
101              << PrintToString(expected_only);
102    printed_header = true;
103  }
104
105  return false;
106}
107
108void ObjectIdInvalidationMapEqMatcher::DescribeTo(::std::ostream* os) const {
109  *os << " is equal to " << PrintToString(expected_);
110}
111
112void ObjectIdInvalidationMapEqMatcher::DescribeNegationTo(
113    ::std::ostream* os) const {
114  *os << " isn't equal to " << PrintToString(expected_);
115}
116
117}  // namespace
118
119Matcher<const ObjectIdInvalidationMap&> Eq(
120    const ObjectIdInvalidationMap& expected) {
121  return MakeMatcher(new ObjectIdInvalidationMapEqMatcher(expected));
122}
123
124}  // namespace syncer
125