Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 52 additions & 31 deletions lib/src/over_react_test/custom_matchers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -292,41 +292,42 @@ class _IsFocused extends Matcher {
/// A matcher that matches the currently focused element (`document.activeElement`).
const Matcher isFocused = _IsFocused();

/// A matcher to verify that a [PropError] is thrown with a provided `propName` and `message`.
/// A matcher to verify that a [PropError] is thrown with the provided [propName] and optional [message].
///
/// __Note__: The message is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
/// This matcher will not work on [PropError]s found within [UiComponent2.propTypes]. When testing
/// prop type validation - use [logsPropError].
///
/// __Deprecated.__ Use [logsPropError] in conjunction with `UiComponent2.propTypes` instead.
@Deprecated('3.0.0')
/// __Note__: The [message] is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
Matcher throwsPropError(String propName, [String message = '']) {
return throwsA(anyOf(
hasToStringValue('V8 Exception'), /* workaround for https://github.com/dart-lang/sdk/issues/26093 */
hasToStringValue(contains('PropError: Prop $propName. $message'.trim()))
));
}

/// A matcher to verify that a [PropError].required is thrown with a provided `propName` and `message`.
/// A matcher to verify that a [PropError.required] is thrown with the provided [propName] and optional [message].
///
/// __Note__: The message is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
/// This matcher will not work on [PropError.required]s found within [UiComponent2.propTypes]. When testing
/// prop type validation - use [logsPropRequiredError].
///
/// __Deprecated.__ Use [logsPropRequiredError] in conjunction with `UiComponent2.propTypes` instead.
@Deprecated('3.0.0')
/// __Note__: The [message] is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
Matcher throwsPropError_Required(String propName, [String message = '']) {
return throwsA(anyOf(
hasToStringValue('V8 Exception'), /* workaround for https://github.com/dart-lang/sdk/issues/26093 */
hasToStringValue(contains('RequiredPropError: Prop $propName is required. $message'.trim()))
));
}

/// A matcher to verify that a [PropError].value is thrown with a provided `invalidValue`, `propName`, and `message`.
/// A matcher to verify that a [PropError.value] is thrown with the provided [invalidValue], [propName],
/// and optional [message].
///
/// __Note__: The message is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
/// This matcher will not work on [PropError.value]s found within [UiComponent2.propTypes]. When testing
/// prop type validation - use [logsPropValueError].
///
/// __Deprecated.__ Use [logsPropValueError] in conjunction with `UiComponent2.propTypes` instead.
@Deprecated('3.0.0')
/// __Note__: The [message] is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
Matcher throwsPropError_Value(dynamic invalidValue, String propName, [String message = '']) {
return throwsA(anyOf(
hasToStringValue('V8 Exception'), /* workaround for https://github.com/dart-lang/sdk/issues/26093 */
Expand All @@ -336,13 +337,14 @@ Matcher throwsPropError_Value(dynamic invalidValue, String propName, [String mes
));
}

/// A matcher to verify that a [PropError] is thrown with a provided `propName`, `prop2Name`, and `message`.
/// A matcher to verify that a [PropError.combination] is thrown with the provided [propName], [prop2Name],
/// and optional [message].
///
/// __Note__: The message is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
/// This matcher will not work on [PropError.combination]s found within [UiComponent2.propTypes]. When testing
/// prop type validation - use [logsPropCombinationError].
///
/// __Deprecated.__ Use [logsPropCombinationError] in conjunction with `UiComponent2.propTypes` instead.
@Deprecated('3.0.0')
/// __Note__: The [message] is matched rather than the [Error] instance due to Dart's wrapping of all `throw`
/// as a [DomException]
Matcher throwsPropError_Combination(String propName, String prop2Name, [String message = '']) {
return throwsA(anyOf(
hasToStringValue('V8 Exception'), /* workaround for https://github.com/dart-lang/sdk/issues/26093 */
Expand Down Expand Up @@ -519,39 +521,58 @@ _PropTypeLogMatcher logsPropTypeWarnings(dynamic expected) =>
/// Related: [logsPropTypeWarning], [logsPropTypeWarnings]
final _PropTypeLogMatcher logsNoPropTypeWarnings = _PropTypeLogMatcher(isEmpty);

/// A matcher to verify that a [PropError] is thrown with a provided `propName` and `message`.
/// A matcher to verify that a [PropError] is returned within [UiComponent2.propTypes]
/// with the provided [propName] and optional [message].
///
/// This matcher only works for [PropError]s that are returned within [UiComponent2.propTypes].
/// If you are testing a [PropError] that is thrown anywhere else within a component, use [throwsPropError].
///
/// This matcher is built on top of [logsPropTypeWarning] and has the same behavior
/// of running a provided callback, swallowing errors that occur, and looking
/// of running the provided callback, swallowing errors that occur, and looking
/// for the expected [PropError] in the resulting logs.
_PropTypeLogMatcher logsPropError(String propName, [String message = '']) {
return logsPropTypeWarning('PropError: Prop $propName. $message'.trim());
}

/// A matcher to verify that a [PropError].required is thrown with a provided `propName` and `message`.
/// A matcher to verify that a [PropError.required] is returned within [UiComponent2.propTypes]
/// with the provided [propName] and optional [message].
///
/// This matcher only works for [PropError.required]s that are returned within [UiComponent2.propTypes].
/// If you are testing a [PropError.required] that is thrown anywhere else within a component,
/// use [throwsPropError_Required].
///
/// This matcher is built on top of [logsPropTypeWarning] and has the same behavior
/// of running a provided callback, swallowing errors that occur, and looking
/// for the expected [PropError] in the resulting logs.
/// of running the provided callback, swallowing errors that occur, and looking
/// for the expected [PropError.required] in the resulting logs.
_PropTypeLogMatcher logsPropRequiredError(String propName, [String message = '']) {
return logsPropTypeWarning('RequiredPropError: Prop $propName is required. $message'.trim());
}

/// A matcher to verify that a [PropError].value is thrown with a provided `invalidValue`, `propName`, and `message`.
/// A matcher to verify that a [PropError.value] is thrown with the provided [invalidValue], [propName],
/// and optional [message].
///
/// This matcher only works for [PropError.value]s that are returned within [UiComponent2.propTypes].
/// If you are testing a [PropError.value] that is thrown anywhere else within a component,
/// use [throwsPropError_Value].
///
/// This matcher is built on top of [logsPropTypeWarning] and has the same behavior
/// of running a provided callback, swallowing errors that occur, and looking
/// for the expected [PropError] in the resulting logs.
/// of running the provided callback, swallowing errors that occur, and looking
/// for the expected [PropError.value] in the resulting logs.
_PropTypeLogMatcher logsPropValueError(dynamic invalidValue, String propName, [String message = '']) {
return logsPropTypeWarning('InvalidPropValueError: Prop $propName set to $invalidValue. '
'$message'.trim());
}

/// A matcher to verify that a [PropError] is thrown with a provided `propName`, `prop2Name`, and `message`.
/// A matcher to verify that a [PropError.combination] is thrown with the provided [propName], [prop2Name],
/// and optional [message].
///
/// This matcher only works for [PropError.combination]s that are returned within [UiComponent2.propTypes].
/// If you are testing a [PropError.combination] that is thrown anywhere else within a component,
/// use [throwsPropError_Combination].
///
/// This matcher is built on top of [logsPropTypeWarning] and has the same behavior
/// of running a provided callback, swallowing errors that occur, and looking
/// for the expected [PropError] in the resulting logs.
/// of running the provided callback, swallowing errors that occur, and looking
/// for the expected [PropError.combination] in the resulting logs.
_PropTypeLogMatcher logsPropCombinationError(String propName, String prop2Name, [String message = '']) {
return logsPropTypeWarning('InvalidPropCombinationError: Prop $propName and prop $prop2Name are set to '
'incompatible values. $message'.trim());
Expand Down
2 changes: 1 addition & 1 deletion lib/src/over_react_test/react_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export 'package:over_react/src/util/react_wrappers.dart';
Element container,
Callback autoTearDownCallback}) {
var renderedInstance;
component = component is component_base.UiProps ? component.build() : component;
component = component is component_base.UiProps ? component() : component;

setComponentZone();

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: over_react_test
version: 2.9.3
version: 2.9.4
description: A library for testing OverReact components
author: Workiva UI Platform Team <uip@workiva.com>
homepage: https://github.com/Workiva/over_react_test/
Expand Down
23 changes: 23 additions & 0 deletions test/over_react_test/react_util_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ part 'react_util_test.over_react.g.dart';
/// Main entry point for ReactUtil testing
main() {
group('ReactUtil', () {
group('render behaves as expected when a UiProps instance is provided', () {
test('(UiComponent)', () {
final renderedInstance = render(Test());
expect(Test(getProps(renderedInstance)).children, isEmpty);
});

test('(UiComponent2)', () {
final renderedInstance = render(Test2());
expect(Test2(getProps(renderedInstance)).children, isEmpty);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified that this test fails without the analogous change in react_util.dart

});
});

test('renderShallow renders a shallow instance of a component', () {
var shallowInstance = renderShallow(Test()());
expect(shallowInstance.type, 'div', reason: 'should be the div ReactElement returned by render()');
Expand Down Expand Up @@ -1253,3 +1265,14 @@ class TestProps extends _$TestProps with _$TestPropsAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const PropsMeta meta = _$metaForTestProps;
}

UiFactory<Test2Props> Test2 =
// ignore: undefined_identifier
_$Test2;

mixin Test2Props on UiProps {}

class Test2Component extends UiComponent2<Test2Props> {
@override
render() => (Dom.div()..addProp('isRenderResult', true))();
}