#!/usr/bin/env python3 # Copyright (c) Meta Platforms, Inc. and affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # pyre-strict import unittest from testing.types import Color, Integers, Messy, Runtime, SimpleError from thrift.py3.reflection import ( inspect, inspectable, NumberType, Qualifier, StructType, ) """ This test contains those reflection use cases we currently support in auto-migrate. The following are not yet supported / implemented: - container reflection (e.g., List__i32, Set__Color) - reflection for structs that have any container fields - services_reflection """ class ReflectionTests(unittest.TestCase): # def test_struct(self) -> None: # x = easy(val=1, an_int=Integers(small=300), name="foo", val_list=[1, 2, 3, 4]) # self.assertTrue(inspectable(x)) # self.assertTrue(inspectable(easy)) # r = inspect(x) # self.assertEqual(r.name, "easy") # self.assertIsInstance(r.kind, StructType) # self.assertEqual(r.kind, StructType.STRUCT) # self.assertEqual(r.annotations, {"anno1": "foo", "bar": "1"}) def test_struct_fields(self) -> None: r = inspect(Messy) self.assertEqual(len(r.fields), 3) self.assertEqual(r.fields[0].id, 1) self.assertEqual(r.fields[0].name, "opt_field") self.assertEqual(r.fields[0].type, str) self.assertEqual(r.fields[0].kind, NumberType.NOT_A_NUMBER) self.assertEqual(r.fields[0].qualifier, Qualifier.OPTIONAL) self.assertEqual(r.fields[0].default, None) self.assertEqual( r.fields[0].annotations, {"some": "annotation", "a.b.c": "d.e.f"} ) self.assertEqual(r.fields[1].id, 3) self.assertEqual(r.fields[1].name, "unq_field") self.assertEqual(r.fields[1].type, str) self.assertEqual(r.fields[1].kind, NumberType.NOT_A_NUMBER) self.assertEqual(r.fields[1].qualifier, Qualifier.UNQUALIFIED) self.assertEqual(r.fields[1].default, "xyzzy") self.assertEqual(r.fields[1].annotations, {}) self.assertEqual(r.fields[2].id, 4) self.assertEqual(r.fields[2].name, "struct_field") self.assertEqual(r.fields[2].type, Runtime) self.assertEqual(r.fields[2].kind, NumberType.NOT_A_NUMBER) self.assertEqual(r.fields[2].qualifier, Qualifier.UNQUALIFIED) self.assertEqual( r.fields[2].default, Runtime(bool_val=True, enum_val=Color.blue, int_list_val=[10, 20, 30]), ) self.assertEqual(r.fields[2].annotations, {}) def test_union(self) -> None: x = Integers(large=100) self.assertTrue(inspectable(x)) self.assertTrue(inspectable(Integers)) r = inspect(x) self.assertEqual(r.name, "Integers") self.assertEqual(r.kind, StructType.UNION) self.assertEqual(r.annotations, {}) def test_exception(self) -> None: x = SimpleError(color=Color.red) self.assertTrue(inspectable(x)) self.assertTrue(inspectable(SimpleError)) r = inspect(x) self.assertEqual(r.name, "SimpleError") self.assertEqual(r.kind, StructType.EXCEPTION) self.assertEqual(r.annotations, {}) # def test_list_element(self) -> None: # x = List__i32([1, 2, 3]) # self.assertTrue(inspectable(x)) # self.assertTrue(inspectable(List__i32)) # r = inspect(x) # self.assertEqual(r.value, int) # self.assertEqual(r.kind, NumberType.I32) # def test_set_element(self) -> None: # x = Set__Color({Color.red, Color.blue}) # self.assertTrue(inspectable(x)) # self.assertTrue(inspectable(Set__Color)) # r = inspect(x) # self.assertEqual(r.value, Color) # self.assertEqual(r.kind, NumberType.NOT_A_NUMBER) # def test_map_key_value(self) -> None: # x = StrStrIntListMapMap({"a": StrI32ListMap({"b": I32List([7, 8, 9])})}) # self.assertTrue(inspectable(x)) # self.assertTrue(inspectable(StrStrIntListMapMap)) # r = inspect(x) # self.assertEqual(r.key, str) # self.assertEqual(r.value, StrI32ListMap) # self.assertEqual(r.key_kind, NumberType.NOT_A_NUMBER) # self.assertEqual(r.value_kind, NumberType.NOT_A_NUMBER) def test_other(self) -> None: x = None self.assertFalse(inspectable(x)) self.assertFalse(inspectable(type(x))) x = 3 self.assertFalse(inspectable(x)) self.assertFalse(inspectable(type(x)))