xref: /aosp_15_r20/external/cronet/base/test/values_test_util.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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