#!/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 import testing.types as _types from testing.builders import ( ColorGroups_Builder, Digits_Builder, easy_Builder, File_Builder, HardError_Builder, Integers_Builder, numerical_Builder, Reserved_Builder, ValueOrError_Builder, ) from thrift.lib.py3.test.auto_migrate_util import brokenInAutoMigrate class BuilderTest(unittest.TestCase): def test_defaults(self) -> None: easy_builder = easy_Builder() self.assertIsNone(easy_builder.val) self.assertIsNone(easy_builder.val_list) self.assertIsNone(easy_builder.name) self.assertIsNone(easy_builder.an_int) file_builder = File_Builder() self.assertIsNone(file_builder.name) self.assertIsNone(file_builder.permissions) self.assertIsNone(file_builder.type) numerical_builder = numerical_Builder() self.assertIsNone(numerical_builder.int_val) self.assertIsNone(numerical_builder.float_val) self.assertIsNone(numerical_builder.int_list) self.assertIsNone(numerical_builder.float_list) self.assertIsNone(numerical_builder.i64_val) def test_build(self) -> None: easy_builder = easy_Builder() easy_builder.val = 42 easy_builder.val_list = [123, 456] easy_builder.name = "foo" easy_builder.an_int = _types.Integers.fromValue(123) easy_obj = easy_builder() self.assertIsInstance(easy_obj, _types.easy) self.assertEqual(easy_obj.val, 42) self.assertEqual(easy_obj.val_list, [123, 456]) self.assertEqual(easy_obj.name, "foo") self.assertEqual(easy_obj.an_int.value, 123) error_builder = HardError_Builder() error_builder.errortext = "oh no!" error_builder.code = 404 error_obj = error_builder() self.assertIsInstance(error_obj, _types.HardError) self.assertEqual(error_obj.errortext, "oh no!") self.assertEqual(error_obj.code, 404) def test_build_with_builder_fields(self) -> None: easy_builder = easy_Builder() integers_builder = Integers_Builder() digits_builder = Digits_Builder() digits_builder.data = [ _types.Integers.fromValue(123), _types.Integers.fromValue(456), ] integers_builder.digits = digits_builder easy_builder.an_int = integers_builder easy_obj = easy_builder() self.assertIsInstance(easy_obj, _types.easy) an_int_value = easy_obj.an_int.value self.assertIsInstance(an_int_value, _types.Digits) self.assertEqual(len(an_int_value.data), 2) v1, v2 = an_int_value.data self.assertEqual(v1.value, 123) self.assertEqual(v2.value, 456) def test_build_with_wrong_type_field(self) -> None: easy_builder = easy_Builder() # pyre-fixme[8]: Attribute has type `Optional[int]`; used as `str`. easy_builder.val = "123" with self.assertRaises(TypeError): easy_builder() # caught at build step easy_builder = easy_Builder() easy_builder.val_list = [ "123", 456, ] # OK now as builder doesn't check list element types with self.assertRaises(TypeError): easy_builder() # caught at build step value_or_error_builder = ValueOrError_Builder() value_or_error_builder.error = ( "wrong!" # OK now as builder takes any type for struct field ) with self.assertRaises(TypeError): value_or_error_builder() # caught at build step @brokenInAutoMigrate() def test_reserved_names(self) -> None: builder = Reserved_Builder() builder.from_ = "from" builder.nonlocal_ = 42 builder.is_cpdef = True obj = builder() self.assertEqual(obj.from_, "from") self.assertEqual(obj.nonlocal_, 42) self.assertTrue(obj.is_cpdef) def test_build_map_field(self) -> None: builder = ColorGroups_Builder() builder.color_map = {_types.Color.red: _types.Color.blue} obj = builder() self.assertEqual(obj.color_map[_types.Color.red], _types.Color.blue)