1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_TEST_VALUES_TEST_UTIL_H_
6 #define BASE_TEST_VALUES_TEST_UTIL_H_
7
8 #include <iosfwd>
9 #include <memory>
10 #include <string>
11 #include <string_view>
12
13 #include "base/files/file_path.h"
14 #include "base/types/expected.h"
15 #include "base/values.h"
16 #include "testing/gmock/include/gmock/gmock-matchers.h"
17
18 namespace base {
19
20 // All the functions below expect that the value for the given path in
21 // the given dictionary equals the given expected value.
22
23 void ExpectDictBooleanValue(bool expected_value,
24 const Value::Dict& dict,
25 std::string_view path);
26
27 void ExpectDictIntegerValue(int expected_value,
28 const Value::Dict& dict,
29 std::string_view path);
30
31 void ExpectDictStringValue(std::string_view expected_value,
32 const Value::Dict& dict,
33 std::string_view path);
34
35 void ExpectDictValue(const Value::Dict& expected_value,
36 const Value::Dict& dict,
37 std::string_view path);
38
39 void ExpectDictValue(const Value& expected_value,
40 const Value::Dict& dict,
41 std::string_view path);
42
43 void ExpectStringValue(const std::string& expected_str, const Value& actual);
44
45 namespace test {
46
47 // A custom GMock matcher which matches if a base::Value::Dict has a key |key|
48 // that is equal to |value|.
49 testing::Matcher<const base::Value::Dict&> DictionaryHasValue(
50 const std::string& key,
51 const base::Value& expected_value);
52
53 // A custom GMock matcher which matches if a base::Value::Dict contains all
54 // key/value pairs from |template_value|.
55 testing::Matcher<const base::Value::Dict&> DictionaryHasValues(
56 const base::Value::Dict& template_value);
57
58 // A custom GMock matcher. For details, see
59 // https://github.com/google/googletest/blob/644319b9f06f6ca9bf69fe791be399061044bc3d/googlemock/docs/CookBook.md#writing-new-polymorphic-matchers
60 class IsJsonMatcher {
61 public:
62 explicit IsJsonMatcher(std::string_view json);
63 explicit IsJsonMatcher(const base::Value& value);
64 explicit IsJsonMatcher(const base::Value::Dict& value);
65 explicit IsJsonMatcher(const base::Value::List& value);
66
67 IsJsonMatcher(const IsJsonMatcher& other);
68 IsJsonMatcher& operator=(const IsJsonMatcher& other);
69
70 ~IsJsonMatcher();
71
72 bool MatchAndExplain(std::string_view json,
73 testing::MatchResultListener* listener) const;
74 bool MatchAndExplain(const base::Value& value,
75 testing::MatchResultListener* listener) const;
76 bool MatchAndExplain(const base::Value::Dict& dict,
77 testing::MatchResultListener* listener) const;
78 bool MatchAndExplain(const base::Value::List& list,
79 testing::MatchResultListener* listener) const;
80 void DescribeTo(std::ostream* os) const;
81 void DescribeNegationTo(std::ostream* os) const;
82
83 private:
84 base::Value expected_value_;
85 };
86
87 // Creates a GMock matcher for testing equivalence of JSON values represented as
88 // either JSON strings or base::Value objects. Parsing of the expected value
89 // uses ParseJson(), which allows trailing commas for convenience. Parsing of
90 // the actual value follows the JSON spec strictly.
91 //
92 // Although it possible to use this matcher when the actual and expected values
93 // are both base::Value objects, there is no advantage in that case to using
94 // this matcher in place of GMock's normal equality semantics.
95 template <typename T>
IsJson(const T & value)96 inline testing::PolymorphicMatcher<IsJsonMatcher> IsJson(const T& value) {
97 return testing::MakePolymorphicMatcher(IsJsonMatcher(value));
98 }
99
100 // Parses `json` as JSON, allowing trailing commas, and returns the resulting
101 // value. If `json` fails to parse, causes an EXPECT failure and returns the
102 // Null Value.
103 Value ParseJson(std::string_view json);
104
105 // Just like ParseJson(), except returns Dicts/Lists. If `json` fails to parse
106 // or is not of the expected type, causes an EXPECT failure and returns an empty
107 // container.
108 Value::Dict ParseJsonDict(std::string_view json);
109 Value::List ParseJsonList(std::string_view json);
110
111 // Similar to `ParseJsonDict`, however it loads its contents from a file.
112 // Returns the parsed `Value::Dict` when successful. Otherwise, it causes an
113 // EXPECT failure, and returns an empty dict.
114 Value::Dict ParseJsonDictFromFile(const FilePath& json_file_path);
115
116 // An enumaration with the possible types of errors when calling
117 // `WriteJsonFile`.
118 enum class WriteJsonError {
119 // Failed to generate a json string with the value provided.
120 kGenerateJsonFailure,
121
122 // Failed to write the json string into a file.
123 kWriteFileFailure,
124 };
125
126 // Serialises `root` as a json string to a file. Returns a empty expected when
127 // successful. Otherwise returns an error.
128 expected<void, WriteJsonError> WriteJsonFile(const FilePath& json_file_path,
129 ValueView root);
130
131 } // namespace test
132 } // namespace base
133
134 #endif // BASE_TEST_VALUES_TEST_UTIL_H_
135