1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #include <ABI48_0_0cxxreact/ABI48_0_0MethodCall.h>
9 
10 #include <folly/json.h>
11 #pragma GCC diagnostic push
12 #pragma GCC diagnostic ignored "-Wsign-compare"
13 #include <gtest/gtest.h>
14 #pragma GCC diagnostic pop
15 
16 using namespace ABI48_0_0facebook::ABI48_0_0React;
17 using dynamic = folly::dynamic;
18 
TEST(parseMethodCalls,SingleReturnCallNoArgs)19 TEST(parseMethodCalls, SingleReturnCallNoArgs) {
20   auto jsText = "[[7],[3],[[]]]";
21   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
22   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
23   auto returnedCall = returnedCalls[0];
24   ABI48_0_0EXPECT_EQ(0, returnedCall.arguments.size());
25   ABI48_0_0EXPECT_EQ(7, returnedCall.moduleId);
26   ABI48_0_0EXPECT_EQ(3, returnedCall.methodId);
27 }
28 
TEST(parseMethodCalls,InvalidReturnFormat)29 TEST(parseMethodCalls, InvalidReturnFormat) {
30   try {
31     auto input = dynamic::object("foo", 1);
32     parseMethodCalls(std::move(input));
33     ADD_FAILURE();
34   } catch (const std::invalid_argument &) {
35     // ignored
36   }
37   try {
38     auto input = dynamic::array(dynamic::object("foo", 1));
39     parseMethodCalls(std::move(input));
40     ADD_FAILURE();
41   } catch (const std::invalid_argument &) {
42     // ignored
43   }
44   try {
45     auto input = dynamic::array(1, 4, dynamic::object("foo", 2));
46     parseMethodCalls(std::move(input));
47     ADD_FAILURE();
48   } catch (const std::invalid_argument &) {
49     // ignored
50   }
51   try {
52     auto input = dynamic::array(
53         dynamic::array(1), dynamic::array(4), dynamic::object("foo", 2));
54     parseMethodCalls(std::move(input));
55     ADD_FAILURE();
56   } catch (const std::invalid_argument &) {
57     // ignored
58   }
59   try {
60     auto input =
61         dynamic::array(dynamic::array(1), dynamic::array(4), dynamic::array());
62     parseMethodCalls(std::move(input));
63     ADD_FAILURE();
64   } catch (const std::invalid_argument &) {
65     // ignored
66   }
67 }
68 
TEST(parseMethodCalls,NumberReturn)69 TEST(parseMethodCalls, NumberReturn) {
70   auto jsText = "[[0],[0],[[\"foobar\"]]]";
71   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
72   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
73   auto returnedCall = returnedCalls[0];
74   ABI48_0_0EXPECT_EQ(1, returnedCall.arguments.size());
75   ABI48_0_0EXPECT_EQ(folly::dynamic::STRING, returnedCall.arguments[0].type());
76   ABI48_0_0EXPECT_EQ("foobar", returnedCall.arguments[0].asString());
77 }
78 
TEST(parseMethodCalls,StringReturn)79 TEST(parseMethodCalls, StringReturn) {
80   auto jsText = "[[0],[0],[[42.16]]]";
81   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
82   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
83   auto returnedCall = returnedCalls[0];
84   ABI48_0_0EXPECT_EQ(1, returnedCall.arguments.size());
85   ABI48_0_0EXPECT_EQ(folly::dynamic::DOUBLE, returnedCall.arguments[0].type());
86   ABI48_0_0EXPECT_EQ(42.16, returnedCall.arguments[0].asDouble());
87 }
88 
TEST(parseMethodCalls,BooleanReturn)89 TEST(parseMethodCalls, BooleanReturn) {
90   auto jsText = "[[0],[0],[[false]]]";
91   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
92   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
93   auto returnedCall = returnedCalls[0];
94   ABI48_0_0EXPECT_EQ(1, returnedCall.arguments.size());
95   ABI48_0_0EXPECT_EQ(folly::dynamic::BOOL, returnedCall.arguments[0].type());
96   ASSERT_FALSE(returnedCall.arguments[0].asBool());
97 }
98 
TEST(parseMethodCalls,NullReturn)99 TEST(parseMethodCalls, NullReturn) {
100   auto jsText = "[[0],[0],[[null]]]";
101   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
102   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
103   auto returnedCall = returnedCalls[0];
104   ABI48_0_0EXPECT_EQ(1, returnedCall.arguments.size());
105   ABI48_0_0EXPECT_EQ(folly::dynamic::NULLT, returnedCall.arguments[0].type());
106 }
107 
TEST(parseMethodCalls,MapReturn)108 TEST(parseMethodCalls, MapReturn) {
109   auto jsText =
110       "[[0],[0],[[{\"foo\": \"hello\", \"bar\": 4.0, \"baz\": true}]]]";
111   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
112   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
113   auto returnedCall = returnedCalls[0];
114   ABI48_0_0EXPECT_EQ(1, returnedCall.arguments.size());
115   ABI48_0_0EXPECT_EQ(folly::dynamic::OBJECT, returnedCall.arguments[0].type());
116   auto &returnedMap = returnedCall.arguments[0];
117   auto foo = returnedMap.at("foo");
118   ABI48_0_0EXPECT_EQ(folly::dynamic("hello"), foo);
119   auto bar = returnedMap.at("bar");
120   ABI48_0_0EXPECT_EQ(folly::dynamic(4.0), bar);
121   auto baz = returnedMap.at("baz");
122   ABI48_0_0EXPECT_EQ(folly::dynamic(true), baz);
123 }
124 
TEST(parseMethodCalls,ArrayReturn)125 TEST(parseMethodCalls, ArrayReturn) {
126   auto jsText = "[[0],[0],[[[\"foo\", 42.0, false]]]]";
127   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
128   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
129   auto returnedCall = returnedCalls[0];
130   ABI48_0_0EXPECT_EQ(1, returnedCall.arguments.size());
131   ABI48_0_0EXPECT_EQ(folly::dynamic::ARRAY, returnedCall.arguments[0].type());
132   auto &returnedArray = returnedCall.arguments[0];
133   ABI48_0_0EXPECT_EQ(3, returnedArray.size());
134   ABI48_0_0EXPECT_EQ(folly::dynamic("foo"), returnedArray[0]);
135   ABI48_0_0EXPECT_EQ(folly::dynamic(42.0), returnedArray[1]);
136   ABI48_0_0EXPECT_EQ(folly::dynamic(false), returnedArray[2]);
137 }
138 
TEST(parseMethodCalls,ReturnMultipleParams)139 TEST(parseMethodCalls, ReturnMultipleParams) {
140   auto jsText = "[[0],[0],[[\"foo\", 14, null, false]]]";
141   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
142   ABI48_0_0EXPECT_EQ(1, returnedCalls.size());
143   auto returnedCall = returnedCalls[0];
144   ABI48_0_0EXPECT_EQ(4, returnedCall.arguments.size());
145   ABI48_0_0EXPECT_EQ(folly::dynamic::STRING, returnedCall.arguments[0].type());
146   ABI48_0_0EXPECT_EQ(folly::dynamic::INT64, returnedCall.arguments[1].type());
147   ABI48_0_0EXPECT_EQ(folly::dynamic::NULLT, returnedCall.arguments[2].type());
148   ABI48_0_0EXPECT_EQ(folly::dynamic::BOOL, returnedCall.arguments[3].type());
149 }
150 
TEST(parseMethodCalls,ParseTwoCalls)151 TEST(parseMethodCalls, ParseTwoCalls) {
152   auto jsText = "[[0,0],[1,1],[[],[]]]";
153   auto returnedCalls = parseMethodCalls(folly::parseJson(jsText));
154   ABI48_0_0EXPECT_EQ(2, returnedCalls.size());
155 }
156