diff --git a/CHANGELOG.md b/CHANGELOG.md index 30a668f24..56e94c0ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # OverReact Changelog +## [4.11.1](https://github.com/Workiva/over_react/compare/4.11.0...4.11.1) +- [#881] Fix disableRequiredPropValidation annotation and add test + ## [4.11.0](https://github.com/Workiva/over_react/compare/4.10.4...4.11.0) - [#879] Backpatch @Props(disableRequiredPropValidation) annotation arg diff --git a/lib/src/builder/parsing/members/props_and_state_util.dart b/lib/src/builder/parsing/members/props_and_state_util.dart index d6ab575f4..960cdcd63 100644 --- a/lib/src/builder/parsing/members/props_and_state_util.dart +++ b/lib/src/builder/parsing/members/props_and_state_util.dart @@ -52,6 +52,7 @@ class _PropsStateStringHelpersImpl extends Object with PropsStateStringHelpers { /// Uses [InstantiatedMeta] to analyze [node] and determine the proper annotation. annotations.TypedMap getPropsOrStateAnnotation(bool isProps, AnnotatedNode node) { + final defaultValue = isProps ? annotations.Props() : annotations.State(); final meta = isProps ? (InstantiatedMeta(node) ?? InstantiatedMeta(node) ?? @@ -62,7 +63,20 @@ annotations.TypedMap getPropsOrStateAnnotation(bool isProps, AnnotatedNode node) // ignore: deprecated_member_use_from_same_package InstantiatedMeta(node)); - return meta?.value ?? (isProps ? annotations.Props() : annotations.State()); + if (meta == null) return defaultValue; + + // Make the `disableRequiredPropValidation` arg a noop until it is implemented in v5. + if (meta.potentiallyIncompleteValue is annotations.Props && + meta.unsupportedArguments.length == 1) { + final arg = meta.unsupportedArguments[0]; + if (arg is NamedExpression && arg.name.label.name == 'disableRequiredPropValidation') { + return annotations.Props( + keyNamespace: meta.potentiallyIncompleteValue.keyNamespace, + ); + } + } + + return meta.value ?? defaultValue; } /// If a [ClassMember] exists in [node] with the name `meta`, this will diff --git a/test/over_react/component_declaration/builder_integration_tests/new_boilerplate/null_safety_validate_required_props_test.dart b/test/over_react/component_declaration/builder_integration_tests/new_boilerplate/null_safety_validate_required_props_test.dart new file mode 100644 index 000000000..709448243 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/new_boilerplate/null_safety_validate_required_props_test.dart @@ -0,0 +1,39 @@ +// Copyright 2024 Workiva Inc. +// +// 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. + +import 'package:over_react/over_react.dart'; +import 'package:react_testing_library/react_testing_library.dart' as rtl; +import 'package:test/test.dart'; + +part 'null_safety_validate_required_props_test.over_react.g.dart'; + +void main() { + // This is just a placeholder test that will be replaced when disableRequiredPropValidation is implemented. + test('@Props(disableRequiredPropValidation) annotation does not throw', () { + expect(() { + rtl.render(ComponentTest()()); + }, returnsNormally); + }); +} + +UiFactory ComponentTest = uiFunction( + (props) {}, + _$ComponentTestConfig, // ignore: undefined_identifier +); + +@Props(disableRequiredPropValidation: {'aProp'}) +mixin ComponentTestProps on UiProps { + @requiredProp + bool aProp; +} diff --git a/test/over_react_component_declaration_test.dart b/test/over_react_component_declaration_test.dart index 617a3fbdb..8d245623c 100644 --- a/test/over_react_component_declaration_test.dart +++ b/test/over_react_component_declaration_test.dart @@ -76,6 +76,7 @@ import 'over_react/component_declaration/builder_integration_tests/new_boilerpla import 'over_react/component_declaration/builder_integration_tests/new_boilerplate/required_accessor_integration_test.dart' as new_boilerplate_required_accessor_integration_test; import 'over_react/component_declaration/builder_integration_tests/new_boilerplate/stateful_component_integration_test.dart' as new_boilerplate_stateful_component_integration_test; import 'over_react/component_declaration/builder_integration_tests/new_boilerplate/unassigned_prop_integration_test.dart' as new_boilerplate_unassigned_prop_integration_test; +import 'over_react/component_declaration/builder_integration_tests/new_boilerplate/null_safety_validate_required_props_test.dart' as new_boilerplate_null_safety_validate_required_props_test; main() { enableTestMode(); @@ -138,4 +139,5 @@ main() { new_boilerplate_required_accessor_integration_test.main(); new_boilerplate_stateful_component_integration_test.main(); new_boilerplate_unassigned_prop_integration_test.main(); + new_boilerplate_null_safety_validate_required_props_test.main(); } diff --git a/test/over_react_component_declaration_test.html b/test/over_react_component_declaration_test.html index 14154933b..3cdbb0e12 100644 --- a/test/over_react_component_declaration_test.html +++ b/test/over_react_component_declaration_test.html @@ -21,6 +21,7 @@ +