1 //          Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef SNOWHOUSE_CONTAINSCONSTRAINT_H
7 #define SNOWHOUSE_CONTAINSCONSTRAINT_H
8 
9 #include <algorithm>
10 #include <map>
11 
12 #include "expressions/expression.h"
13 
14 namespace snowhouse
15 {
16   template<typename ContainerType>
17   struct find_in_container_traits
18   {
19     template<typename ExpectedType>
findfind_in_container_traits20     static bool find(const ContainerType& container, const ExpectedType& expected)
21     {
22       return std::find(container.begin(), container.end(), expected) != container.end();
23     }
24   };
25 
26   template<typename KeyType, typename ValueType>
27   struct find_in_container_traits<std::map<KeyType, ValueType> >
28   {
29     template<typename ExpectedType>
30     static bool find(const std::map<KeyType, ValueType>& container, const ExpectedType& expected)
31     {
32       return container.find(expected) != container.end();
33     }
34   };
35 
36   template<typename ExpectedType>
37   struct ContainsConstraint : Expression<ContainsConstraint<ExpectedType> >
38   {
39     ContainsConstraint(const ExpectedType& expected)
40         : m_expected(expected)
41     {
42     }
43 
44     template<typename ActualType>
45     bool operator()(const ActualType& actual) const
46     {
47       return find_in_container_traits<ActualType>::find(actual, m_expected);
48     }
49 
50     bool operator()(const std::string& actual) const
51     {
52       return actual.find(m_expected) != actual.npos;
53     }
54 
55     ExpectedType m_expected;
56   };
57 
58   template<typename ExpectedType>
59   inline ContainsConstraint<ExpectedType> Contains(const ExpectedType& expected)
60   {
61     return ContainsConstraint<ExpectedType>(expected);
62   }
63 
64   inline ContainsConstraint<std::string> Contains(const char* expected)
65   {
66     return ContainsConstraint<std::string>(expected);
67   }
68 
69   template<typename ExpectedType>
70   struct Stringizer<ContainsConstraint<ExpectedType> >
71   {
72     static std::string ToString(const ContainsConstraint<ExpectedType>& constraint)
73     {
74       std::ostringstream builder;
75       builder << "contains " << snowhouse::Stringize(constraint.m_expected);
76 
77       return builder.str();
78     }
79   };
80 }
81 
82 #endif
83