xref: /aosp_15_r20/external/cronet/base/test/values_test_util.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/test/values_test_util.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker #include <ostream>
9*6777b538SAndroid Build Coastguard Worker #include <string_view>
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/json/json_reader.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/json/json_writer.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/types/optional_util.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
19*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker namespace base {
22*6777b538SAndroid Build Coastguard Worker 
ExpectDictBooleanValue(bool expected_value,const Value::Dict & dict,std::string_view path)23*6777b538SAndroid Build Coastguard Worker void ExpectDictBooleanValue(bool expected_value,
24*6777b538SAndroid Build Coastguard Worker                             const Value::Dict& dict,
25*6777b538SAndroid Build Coastguard Worker                             std::string_view path) {
26*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(dict.FindBoolByDottedPath(path), std::make_optional(expected_value))
27*6777b538SAndroid Build Coastguard Worker       << path;
28*6777b538SAndroid Build Coastguard Worker }
29*6777b538SAndroid Build Coastguard Worker 
ExpectDictIntegerValue(int expected_value,const Value::Dict & dict,std::string_view path)30*6777b538SAndroid Build Coastguard Worker void ExpectDictIntegerValue(int expected_value,
31*6777b538SAndroid Build Coastguard Worker                             const Value::Dict& dict,
32*6777b538SAndroid Build Coastguard Worker                             std::string_view path) {
33*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(dict.FindIntByDottedPath(path), std::make_optional(expected_value))
34*6777b538SAndroid Build Coastguard Worker       << path;
35*6777b538SAndroid Build Coastguard Worker }
36*6777b538SAndroid Build Coastguard Worker 
ExpectDictStringValue(std::string_view expected_value,const Value::Dict & dict,std::string_view path)37*6777b538SAndroid Build Coastguard Worker void ExpectDictStringValue(std::string_view expected_value,
38*6777b538SAndroid Build Coastguard Worker                            const Value::Dict& dict,
39*6777b538SAndroid Build Coastguard Worker                            std::string_view path) {
40*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OptionalFromPtr(dict.FindStringByDottedPath(path)),
41*6777b538SAndroid Build Coastguard Worker             std::make_optional(expected_value))
42*6777b538SAndroid Build Coastguard Worker       << path;
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker 
ExpectDictValue(const Value::Dict & expected_value,const Value::Dict & dict,std::string_view path)45*6777b538SAndroid Build Coastguard Worker void ExpectDictValue(const Value::Dict& expected_value,
46*6777b538SAndroid Build Coastguard Worker                      const Value::Dict& dict,
47*6777b538SAndroid Build Coastguard Worker                      std::string_view path) {
48*6777b538SAndroid Build Coastguard Worker   const Value* found_value = dict.FindByDottedPath(path);
49*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(found_value) << path;
50*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(*found_value, expected_value) << path;
51*6777b538SAndroid Build Coastguard Worker }
52*6777b538SAndroid Build Coastguard Worker 
ExpectDictValue(const Value & expected_value,const Value::Dict & dict,std::string_view path)53*6777b538SAndroid Build Coastguard Worker void ExpectDictValue(const Value& expected_value,
54*6777b538SAndroid Build Coastguard Worker                      const Value::Dict& dict,
55*6777b538SAndroid Build Coastguard Worker                      std::string_view path) {
56*6777b538SAndroid Build Coastguard Worker   const Value* found_value = dict.FindByDottedPath(path);
57*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(found_value) << path;
58*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(*found_value, expected_value) << path;
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker 
ExpectStringValue(const std::string & expected_str,const Value & actual)61*6777b538SAndroid Build Coastguard Worker void ExpectStringValue(const std::string& expected_str, const Value& actual) {
62*6777b538SAndroid Build Coastguard Worker   const std::string* maybe_string = actual.GetIfString();
63*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(maybe_string);
64*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_str, *maybe_string);
65*6777b538SAndroid Build Coastguard Worker }
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker namespace test {
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker namespace {
70*6777b538SAndroid Build Coastguard Worker 
FormatAsJSON(ValueView value)71*6777b538SAndroid Build Coastguard Worker std::string FormatAsJSON(ValueView value) {
72*6777b538SAndroid Build Coastguard Worker   std::string json;
73*6777b538SAndroid Build Coastguard Worker   JSONWriter::Write(value, &json);
74*6777b538SAndroid Build Coastguard Worker   return json;
75*6777b538SAndroid Build Coastguard Worker }
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker class DictionaryHasValueMatcher
78*6777b538SAndroid Build Coastguard Worker     : public testing::MatcherInterface<const base::Value::Dict&> {
79*6777b538SAndroid Build Coastguard Worker  public:
DictionaryHasValueMatcher(const std::string & key,const base::Value & expected_value)80*6777b538SAndroid Build Coastguard Worker   DictionaryHasValueMatcher(const std::string& key,
81*6777b538SAndroid Build Coastguard Worker                             const base::Value& expected_value)
82*6777b538SAndroid Build Coastguard Worker       : key_(key), expected_value_(expected_value.Clone()) {}
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker   DictionaryHasValueMatcher(const DictionaryHasValueMatcher& other) = delete;
85*6777b538SAndroid Build Coastguard Worker   DictionaryHasValueMatcher& operator=(const DictionaryHasValueMatcher& other) =
86*6777b538SAndroid Build Coastguard Worker       delete;
87*6777b538SAndroid Build Coastguard Worker 
MatchAndExplain(const base::Value::Dict & value,testing::MatchResultListener * listener) const88*6777b538SAndroid Build Coastguard Worker   bool MatchAndExplain(const base::Value::Dict& value,
89*6777b538SAndroid Build Coastguard Worker                        testing::MatchResultListener* listener) const override {
90*6777b538SAndroid Build Coastguard Worker     const base::Value* sub_value = value.Find(key_);
91*6777b538SAndroid Build Coastguard Worker     if (!sub_value) {
92*6777b538SAndroid Build Coastguard Worker       *listener << "Dictionary '" << FormatAsJSON(value)
93*6777b538SAndroid Build Coastguard Worker                 << "' does not have key '" << key_ << "'";
94*6777b538SAndroid Build Coastguard Worker       return false;
95*6777b538SAndroid Build Coastguard Worker     }
96*6777b538SAndroid Build Coastguard Worker     if (*sub_value != expected_value_) {
97*6777b538SAndroid Build Coastguard Worker       *listener << "Dictionary value under key '" << key_ << "' is '"
98*6777b538SAndroid Build Coastguard Worker                 << FormatAsJSON(*sub_value) << "', expected '"
99*6777b538SAndroid Build Coastguard Worker                 << FormatAsJSON(expected_value_) << "'";
100*6777b538SAndroid Build Coastguard Worker       return false;
101*6777b538SAndroid Build Coastguard Worker     }
102*6777b538SAndroid Build Coastguard Worker     return true;
103*6777b538SAndroid Build Coastguard Worker   }
104*6777b538SAndroid Build Coastguard Worker 
DescribeTo(std::ostream * os) const105*6777b538SAndroid Build Coastguard Worker   void DescribeTo(std::ostream* os) const override {
106*6777b538SAndroid Build Coastguard Worker     *os << "has key '" << key_ << "' with value '"
107*6777b538SAndroid Build Coastguard Worker         << FormatAsJSON(expected_value_) << "'";
108*6777b538SAndroid Build Coastguard Worker   }
109*6777b538SAndroid Build Coastguard Worker 
DescribeNegationTo(std::ostream * os) const110*6777b538SAndroid Build Coastguard Worker   void DescribeNegationTo(std::ostream* os) const override {
111*6777b538SAndroid Build Coastguard Worker     *os << "does not have key '" << key_ << "' with value '"
112*6777b538SAndroid Build Coastguard Worker         << FormatAsJSON(expected_value_) << "'";
113*6777b538SAndroid Build Coastguard Worker   }
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker  private:
116*6777b538SAndroid Build Coastguard Worker   const std::string key_;
117*6777b538SAndroid Build Coastguard Worker   const base::Value expected_value_;
118*6777b538SAndroid Build Coastguard Worker };
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker class DictionaryHasValuesMatcher
121*6777b538SAndroid Build Coastguard Worker     : public testing::MatcherInterface<const base::Value::Dict&> {
122*6777b538SAndroid Build Coastguard Worker  public:
DictionaryHasValuesMatcher(const base::Value::Dict & template_value)123*6777b538SAndroid Build Coastguard Worker   explicit DictionaryHasValuesMatcher(const base::Value::Dict& template_value)
124*6777b538SAndroid Build Coastguard Worker       : template_value_(template_value.Clone()) {}
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker   DictionaryHasValuesMatcher(const DictionaryHasValuesMatcher& other) = delete;
127*6777b538SAndroid Build Coastguard Worker   DictionaryHasValuesMatcher& operator=(
128*6777b538SAndroid Build Coastguard Worker       const DictionaryHasValuesMatcher& other) = delete;
129*6777b538SAndroid Build Coastguard Worker 
MatchAndExplain(const base::Value::Dict & value,testing::MatchResultListener * listener) const130*6777b538SAndroid Build Coastguard Worker   bool MatchAndExplain(const base::Value::Dict& value,
131*6777b538SAndroid Build Coastguard Worker                        testing::MatchResultListener* listener) const override {
132*6777b538SAndroid Build Coastguard Worker     bool ok = true;
133*6777b538SAndroid Build Coastguard Worker     for (auto template_dict_item : template_value_) {
134*6777b538SAndroid Build Coastguard Worker       const base::Value* sub_value = value.Find(template_dict_item.first);
135*6777b538SAndroid Build Coastguard Worker       if (!sub_value) {
136*6777b538SAndroid Build Coastguard Worker         *listener << "\nDictionary does not have key '"
137*6777b538SAndroid Build Coastguard Worker                   << template_dict_item.first << "'";
138*6777b538SAndroid Build Coastguard Worker         ok = false;
139*6777b538SAndroid Build Coastguard Worker         continue;
140*6777b538SAndroid Build Coastguard Worker       }
141*6777b538SAndroid Build Coastguard Worker       if (*sub_value != template_dict_item.second) {
142*6777b538SAndroid Build Coastguard Worker         *listener << "\nDictionary value under key '"
143*6777b538SAndroid Build Coastguard Worker                   << template_dict_item.first << "' is '"
144*6777b538SAndroid Build Coastguard Worker                   << FormatAsJSON(*sub_value) << "', expected '"
145*6777b538SAndroid Build Coastguard Worker                   << FormatAsJSON(template_dict_item.second) << "'";
146*6777b538SAndroid Build Coastguard Worker         ok = false;
147*6777b538SAndroid Build Coastguard Worker       }
148*6777b538SAndroid Build Coastguard Worker     }
149*6777b538SAndroid Build Coastguard Worker     return ok;
150*6777b538SAndroid Build Coastguard Worker   }
151*6777b538SAndroid Build Coastguard Worker 
DescribeTo(std::ostream * os) const152*6777b538SAndroid Build Coastguard Worker   void DescribeTo(std::ostream* os) const override {
153*6777b538SAndroid Build Coastguard Worker     *os << "contains all key-values from '" << FormatAsJSON(template_value_)
154*6777b538SAndroid Build Coastguard Worker         << "'";
155*6777b538SAndroid Build Coastguard Worker   }
156*6777b538SAndroid Build Coastguard Worker 
DescribeNegationTo(std::ostream * os) const157*6777b538SAndroid Build Coastguard Worker   void DescribeNegationTo(std::ostream* os) const override {
158*6777b538SAndroid Build Coastguard Worker     *os << "does not contain key-values from '" << FormatAsJSON(template_value_)
159*6777b538SAndroid Build Coastguard Worker         << "'";
160*6777b538SAndroid Build Coastguard Worker   }
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker  private:
163*6777b538SAndroid Build Coastguard Worker   const base::Value::Dict template_value_;
164*6777b538SAndroid Build Coastguard Worker };
165*6777b538SAndroid Build Coastguard Worker 
166*6777b538SAndroid Build Coastguard Worker // Attempts to parse `json` as JSON. Returns resulting Value on success, has an
167*6777b538SAndroid Build Coastguard Worker // EXPECT failure and returns nullopt on failure. If `expected_type` is
168*6777b538SAndroid Build Coastguard Worker // provided, treats `json` parsing as a Value of a different type as a failure.
169*6777b538SAndroid Build Coastguard Worker //
ParseJsonHelper(std::string_view json,std::optional<Value::Type> expected_type)170*6777b538SAndroid Build Coastguard Worker std::optional<Value> ParseJsonHelper(std::string_view json,
171*6777b538SAndroid Build Coastguard Worker                                      std::optional<Value::Type> expected_type) {
172*6777b538SAndroid Build Coastguard Worker   auto result = JSONReader::ReadAndReturnValueWithError(
173*6777b538SAndroid Build Coastguard Worker       json, JSON_PARSE_CHROMIUM_EXTENSIONS | JSON_ALLOW_TRAILING_COMMAS);
174*6777b538SAndroid Build Coastguard Worker   if (!result.has_value()) {
175*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE() << "Failed to parse \"" << json
176*6777b538SAndroid Build Coastguard Worker                   << "\": " << result.error().message;
177*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
178*6777b538SAndroid Build Coastguard Worker   }
179*6777b538SAndroid Build Coastguard Worker   if (expected_type && result->type() != *expected_type) {
180*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE() << "JSON is of wrong type: " << json;
181*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
182*6777b538SAndroid Build Coastguard Worker   }
183*6777b538SAndroid Build Coastguard Worker   return std::move(*result);
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker }  // namespace
187*6777b538SAndroid Build Coastguard Worker 
DictionaryHasValue(const std::string & key,const base::Value & expected_value)188*6777b538SAndroid Build Coastguard Worker testing::Matcher<const base::Value::Dict&> DictionaryHasValue(
189*6777b538SAndroid Build Coastguard Worker     const std::string& key,
190*6777b538SAndroid Build Coastguard Worker     const base::Value& expected_value) {
191*6777b538SAndroid Build Coastguard Worker   return testing::MakeMatcher(
192*6777b538SAndroid Build Coastguard Worker       new DictionaryHasValueMatcher(key, expected_value));
193*6777b538SAndroid Build Coastguard Worker }
194*6777b538SAndroid Build Coastguard Worker 
DictionaryHasValues(const base::Value::Dict & template_value)195*6777b538SAndroid Build Coastguard Worker testing::Matcher<const base::Value::Dict&> DictionaryHasValues(
196*6777b538SAndroid Build Coastguard Worker     const base::Value::Dict& template_value) {
197*6777b538SAndroid Build Coastguard Worker   return testing::MakeMatcher(new DictionaryHasValuesMatcher(template_value));
198*6777b538SAndroid Build Coastguard Worker }
199*6777b538SAndroid Build Coastguard Worker 
IsJsonMatcher(std::string_view json)200*6777b538SAndroid Build Coastguard Worker IsJsonMatcher::IsJsonMatcher(std::string_view json)
201*6777b538SAndroid Build Coastguard Worker     : expected_value_(test::ParseJson(json)) {}
202*6777b538SAndroid Build Coastguard Worker 
IsJsonMatcher(const base::Value & value)203*6777b538SAndroid Build Coastguard Worker IsJsonMatcher::IsJsonMatcher(const base::Value& value)
204*6777b538SAndroid Build Coastguard Worker     : expected_value_(value.Clone()) {}
205*6777b538SAndroid Build Coastguard Worker 
IsJsonMatcher(const base::Value::Dict & value)206*6777b538SAndroid Build Coastguard Worker IsJsonMatcher::IsJsonMatcher(const base::Value::Dict& value)
207*6777b538SAndroid Build Coastguard Worker     : expected_value_(base::Value(value.Clone())) {}
208*6777b538SAndroid Build Coastguard Worker 
IsJsonMatcher(const base::Value::List & value)209*6777b538SAndroid Build Coastguard Worker IsJsonMatcher::IsJsonMatcher(const base::Value::List& value)
210*6777b538SAndroid Build Coastguard Worker     : expected_value_(base::Value(value.Clone())) {}
211*6777b538SAndroid Build Coastguard Worker 
IsJsonMatcher(const IsJsonMatcher & other)212*6777b538SAndroid Build Coastguard Worker IsJsonMatcher::IsJsonMatcher(const IsJsonMatcher& other)
213*6777b538SAndroid Build Coastguard Worker     : expected_value_(other.expected_value_.Clone()) {}
214*6777b538SAndroid Build Coastguard Worker 
operator =(const IsJsonMatcher & other)215*6777b538SAndroid Build Coastguard Worker IsJsonMatcher& IsJsonMatcher::operator=(const IsJsonMatcher& other) {
216*6777b538SAndroid Build Coastguard Worker   expected_value_ = other.expected_value_.Clone();
217*6777b538SAndroid Build Coastguard Worker   return *this;
218*6777b538SAndroid Build Coastguard Worker }
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker IsJsonMatcher::~IsJsonMatcher() = default;
221*6777b538SAndroid Build Coastguard Worker 
MatchAndExplain(std::string_view json,testing::MatchResultListener * listener) const222*6777b538SAndroid Build Coastguard Worker bool IsJsonMatcher::MatchAndExplain(
223*6777b538SAndroid Build Coastguard Worker     std::string_view json,
224*6777b538SAndroid Build Coastguard Worker     testing::MatchResultListener* listener) const {
225*6777b538SAndroid Build Coastguard Worker   // This is almost the same logic as ParseJson, but the parser uses stricter
226*6777b538SAndroid Build Coastguard Worker   // options for JSON data that is assumed to be generated by the code under
227*6777b538SAndroid Build Coastguard Worker   // test rather than written by hand as part of a unit test.
228*6777b538SAndroid Build Coastguard Worker   auto ret = JSONReader::ReadAndReturnValueWithError(json, JSON_PARSE_RFC);
229*6777b538SAndroid Build Coastguard Worker   if (!ret.has_value()) {
230*6777b538SAndroid Build Coastguard Worker     *listener << "Failed to parse \"" << json << "\": " << ret.error().message;
231*6777b538SAndroid Build Coastguard Worker     return false;
232*6777b538SAndroid Build Coastguard Worker   }
233*6777b538SAndroid Build Coastguard Worker   return MatchAndExplain(*ret, listener);
234*6777b538SAndroid Build Coastguard Worker }
235*6777b538SAndroid Build Coastguard Worker 
MatchAndExplain(const base::Value & value,testing::MatchResultListener *) const236*6777b538SAndroid Build Coastguard Worker bool IsJsonMatcher::MatchAndExplain(
237*6777b538SAndroid Build Coastguard Worker     const base::Value& value,
238*6777b538SAndroid Build Coastguard Worker     testing::MatchResultListener* /* listener */) const {
239*6777b538SAndroid Build Coastguard Worker   return expected_value_ == value;
240*6777b538SAndroid Build Coastguard Worker }
241*6777b538SAndroid Build Coastguard Worker 
MatchAndExplain(const base::Value::Dict & dict,testing::MatchResultListener *) const242*6777b538SAndroid Build Coastguard Worker bool IsJsonMatcher::MatchAndExplain(
243*6777b538SAndroid Build Coastguard Worker     const base::Value::Dict& dict,
244*6777b538SAndroid Build Coastguard Worker     testing::MatchResultListener* /* listener */) const {
245*6777b538SAndroid Build Coastguard Worker   return expected_value_.is_dict() && expected_value_.GetDict() == dict;
246*6777b538SAndroid Build Coastguard Worker }
247*6777b538SAndroid Build Coastguard Worker 
MatchAndExplain(const base::Value::List & list,testing::MatchResultListener *) const248*6777b538SAndroid Build Coastguard Worker bool IsJsonMatcher::MatchAndExplain(
249*6777b538SAndroid Build Coastguard Worker     const base::Value::List& list,
250*6777b538SAndroid Build Coastguard Worker     testing::MatchResultListener* /* listener */) const {
251*6777b538SAndroid Build Coastguard Worker   return expected_value_.is_list() && expected_value_.GetList() == list;
252*6777b538SAndroid Build Coastguard Worker }
253*6777b538SAndroid Build Coastguard Worker 
DescribeTo(std::ostream * os) const254*6777b538SAndroid Build Coastguard Worker void IsJsonMatcher::DescribeTo(std::ostream* os) const {
255*6777b538SAndroid Build Coastguard Worker   *os << "is the JSON value " << expected_value_;
256*6777b538SAndroid Build Coastguard Worker }
257*6777b538SAndroid Build Coastguard Worker 
DescribeNegationTo(std::ostream * os) const258*6777b538SAndroid Build Coastguard Worker void IsJsonMatcher::DescribeNegationTo(std::ostream* os) const {
259*6777b538SAndroid Build Coastguard Worker   *os << "is not the JSON value " << expected_value_;
260*6777b538SAndroid Build Coastguard Worker }
261*6777b538SAndroid Build Coastguard Worker 
ParseJson(std::string_view json)262*6777b538SAndroid Build Coastguard Worker Value ParseJson(std::string_view json) {
263*6777b538SAndroid Build Coastguard Worker   std::optional<Value> result =
264*6777b538SAndroid Build Coastguard Worker       ParseJsonHelper(json, /*expected_type=*/std::nullopt);
265*6777b538SAndroid Build Coastguard Worker   return result.has_value() ? std::move(*result) : Value();
266*6777b538SAndroid Build Coastguard Worker }
267*6777b538SAndroid Build Coastguard Worker 
ParseJsonDict(std::string_view json)268*6777b538SAndroid Build Coastguard Worker Value::Dict ParseJsonDict(std::string_view json) {
269*6777b538SAndroid Build Coastguard Worker   std::optional<Value> result =
270*6777b538SAndroid Build Coastguard Worker       ParseJsonHelper(json, /*expected_type=*/Value::Type::DICT);
271*6777b538SAndroid Build Coastguard Worker   return result.has_value() ? std::move(*result).TakeDict() : Value::Dict();
272*6777b538SAndroid Build Coastguard Worker }
273*6777b538SAndroid Build Coastguard Worker 
ParseJsonList(std::string_view json)274*6777b538SAndroid Build Coastguard Worker Value::List ParseJsonList(std::string_view json) {
275*6777b538SAndroid Build Coastguard Worker   std::optional<Value> result =
276*6777b538SAndroid Build Coastguard Worker       ParseJsonHelper(json, /*expected_type=*/Value::Type::LIST);
277*6777b538SAndroid Build Coastguard Worker   return result.has_value() ? std::move(*result).TakeList() : Value::List();
278*6777b538SAndroid Build Coastguard Worker }
279*6777b538SAndroid Build Coastguard Worker 
ParseJsonDictFromFile(const FilePath & json_file_path)280*6777b538SAndroid Build Coastguard Worker Value::Dict ParseJsonDictFromFile(const FilePath& json_file_path) {
281*6777b538SAndroid Build Coastguard Worker   std::string json;
282*6777b538SAndroid Build Coastguard Worker   if (!ReadFileToString(json_file_path, &json)) {
283*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE() << "Failed to load json file for parsing. path="
284*6777b538SAndroid Build Coastguard Worker                   << json_file_path;
285*6777b538SAndroid Build Coastguard Worker     return {};
286*6777b538SAndroid Build Coastguard Worker   }
287*6777b538SAndroid Build Coastguard Worker   return ParseJsonDict(json);
288*6777b538SAndroid Build Coastguard Worker }
289*6777b538SAndroid Build Coastguard Worker 
WriteJsonFile(const FilePath & json_file_path,ValueView root)290*6777b538SAndroid Build Coastguard Worker expected<void, WriteJsonError> WriteJsonFile(const FilePath& json_file_path,
291*6777b538SAndroid Build Coastguard Worker                                              ValueView root) {
292*6777b538SAndroid Build Coastguard Worker   std::string json;
293*6777b538SAndroid Build Coastguard Worker   if (!JSONWriter::Write(root, &json)) {
294*6777b538SAndroid Build Coastguard Worker     return unexpected(WriteJsonError::kGenerateJsonFailure);
295*6777b538SAndroid Build Coastguard Worker   }
296*6777b538SAndroid Build Coastguard Worker   if (!WriteFile(json_file_path, json)) {
297*6777b538SAndroid Build Coastguard Worker     return unexpected(WriteJsonError::kWriteFileFailure);
298*6777b538SAndroid Build Coastguard Worker   }
299*6777b538SAndroid Build Coastguard Worker   return {};
300*6777b538SAndroid Build Coastguard Worker }
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker }  // namespace test
303*6777b538SAndroid Build Coastguard Worker }  // namespace base
304