Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.x - Dart 1] Update prop typedef to work around Dart 2.6 compiler regression #384

Closed
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
7 changes: 5 additions & 2 deletions lib/src/component/prop_typedefs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ import 'package:over_react/over_react.dart';
import 'package:over_react/src/component_declaration/component_base.dart' as component_base;
import 'package:react/react_client.dart';

/// A typedef for props that allow a custom rendering function to be provided to render some part of a component.
typedef ReactElement CustomRenderFunction<TProps extends UiProps, TState extends UiState, TComponent extends component_base.UiComponent<TProps>> (TProps props, TState state, TComponent component);
/// A custom rendering prop typedef that allows a custom rendering function to be provided
/// with the current [props] and [state] of the [component].
typedef ReactElement CustomRenderFunction<T extends UiProps,
S extends UiState,
C extends component_base.UiComponent> (T props, S state, C component);
11 changes: 11 additions & 0 deletions test/over_react/component/fixtures/prop_typedef_fixtures.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
library prop_tyepdef_test_fixtures;

import 'package:over_react/over_react.dart';

part 'prop_typedef_fixtures/abstract_component_with_custom_render_prop.dart';
part 'prop_typedef_fixtures/component_consuming_abstract_custom_render_prop.dart';
part 'prop_typedef_fixtures/component_consuming_custom_render_prop.dart';
part 'prop_typedef_fixtures/component_extending_from_abstract_component_with_custom_render_prop.dart';
part 'prop_typedef_fixtures/component_with_custom_render_prop.dart';

part 'prop_typedef_fixtures.over_react.g.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2019 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.

part of prop_tyepdef_test_fixtures;

@AbstractProps()
abstract class _$TestAbstractCustomRendererComponentProps extends UiProps {
CustomRenderFunction customRenderer;
CustomRenderFunction<TestAbstractCustomRendererComponentProps,
TestAbstractCustomRendererComponentState,
TestAbstractCustomRendererComponentComponent> parameterizedCustomRenderer;

String somePropKey;
}

@AbstractState()
abstract class _$TestAbstractCustomRendererComponentState extends UiState {
String someStateKey;
}

@AbstractComponent()
abstract class TestAbstractCustomRendererComponentComponent<T extends TestAbstractCustomRendererComponentProps,
S extends TestAbstractCustomRendererComponentState>
extends UiStatefulComponent<T, S> {}

// AF-3369 This will be removed once the transition to Dart 2 is complete.
// ignore: mixin_of_non_class, undefined_class
abstract class TestAbstractCustomRendererComponentProps extends _$TestAbstractCustomRendererComponentProps with _$TestAbstractCustomRendererComponentPropsAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const PropsMeta meta = $metaForTestAbstractCustomRendererComponentProps;
}

// AF-3369 This will be removed once the transition to Dart 2 is complete.
// ignore: mixin_of_non_class, undefined_class
abstract class TestAbstractCustomRendererComponentState extends _$TestAbstractCustomRendererComponentState with _$TestAbstractCustomRendererComponentStateAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const StateMeta meta = $metaForTestAbstractCustomRendererComponentState;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2019 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.

// ignore_for_file: avoid_as

part of prop_tyepdef_test_fixtures;

@Factory()
UiFactory<TestConsumingAbstractCustomRendererComponentProps> TestConsumingAbstractCustomRendererComponent =
// ignore: undefined_identifier
$TestConsumingAbstractCustomRendererComponent;

@Props()
class _$TestConsumingAbstractCustomRendererComponentProps extends UiProps {
String propKeyValueToTest;
String stateKeyValueToTest;
}

@Component()
class TestConsumingAbstractCustomRendererComponentComponent
extends UiComponent<TestConsumingAbstractCustomRendererComponentProps> {
@override
render() {
return (TestCustomRendererFromAbstractComponent()
..somePropKey = props.propKeyValueToTest
..someInitialStateKeyValue = props.stateKeyValueToTest
..customRenderer = (props, state, component) {
return (Dom.div()
..addTestId('customRendererContainer')
)(
'props.somePropKey: ${(props as TestCustomRendererFromAbstractComponentProps).somePropKey} \n'
'props.someStateKey: ${(state as TestCustomRendererFromAbstractComponentState).someStateKey}'
);
}
..parameterizedCustomRenderer = (props, state, component) {
return (Dom.div()
..addTestId('parameterizedCustomRendererContainer')
)(
'props.somePropKey: ${props.somePropKey} \n'
'props.someStateKey: ${state.someStateKey}'
);
}
)();
}
}

// AF-3369 This will be removed once the transition to Dart 2 is complete.
// ignore: mixin_of_non_class, undefined_class
class TestConsumingAbstractCustomRendererComponentProps extends _$TestConsumingAbstractCustomRendererComponentProps with _$TestConsumingAbstractCustomRendererComponentPropsAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const PropsMeta meta = $metaForTestConsumingAbstractCustomRendererComponentProps;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2019 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.

// ignore_for_file: avoid_as

part of prop_tyepdef_test_fixtures;

@Factory()
UiFactory<TestConsumingCustomRendererComponentProps> TestConsumingCustomRendererComponent =
// ignore: undefined_identifier
$TestConsumingCustomRendererComponent;

@Props()
class _$TestConsumingCustomRendererComponentProps extends UiProps {
String propKeyValueToTest;
String stateKeyValueToTest;
}

@Component()
class TestConsumingCustomRendererComponentComponent extends UiComponent<TestConsumingCustomRendererComponentProps> {
@override
render() {
return (TestCustomRendererComponent()
..somePropKey = props.propKeyValueToTest
..someInitialStateKeyValue = props.stateKeyValueToTest
..customRenderer = (props, state, component) {
return (Dom.div()
..addTestId('customRendererContainer')
)(
'props.somePropKey: ${(props as TestCustomRendererComponentProps).somePropKey} \n'
'props.someStateKey: ${(state as TestCustomRendererComponentState).someStateKey}'
);
}
..parameterizedCustomRenderer = (props, state, component) {
return (Dom.div()
..addTestId('parameterizedCustomRendererContainer')
)(
'props.somePropKey: ${props.somePropKey} \n'
'props.someStateKey: ${state.someStateKey}'
);
}
)();
}
}

// ignore: mixin_of_non_class, undefined_class
class TestConsumingCustomRendererComponentProps extends _$TestConsumingCustomRendererComponentProps with _$TestConsumingCustomRendererComponentPropsAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const PropsMeta meta = $metaForTestConsumingCustomRendererComponentProps;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2019 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.

part of prop_tyepdef_test_fixtures;

@Factory()
UiFactory<TestCustomRendererFromAbstractComponentProps> TestCustomRendererFromAbstractComponent =
// ignore: undefined_identifier
$TestCustomRendererFromAbstractComponent;

@Props()
class _$TestCustomRendererFromAbstractComponentProps extends TestAbstractCustomRendererComponentProps {
String someInitialStateKeyValue;
}

@State()
class _$TestCustomRendererFromAbstractComponentState extends TestAbstractCustomRendererComponentState {}

@Component()
class TestCustomRendererFromAbstractComponentComponent
extends TestAbstractCustomRendererComponentComponent<TestCustomRendererFromAbstractComponentProps,
TestCustomRendererFromAbstractComponentState> {
@override
Map getInitialState() => (newState()..someStateKey = props.someInitialStateKeyValue);

@override
render() {
return Dom.div()(
props.customRenderer(props, state, this),
props.parameterizedCustomRenderer(props, state, this),
);
}
}

// ignore: mixin_of_non_class, undefined_class
class TestCustomRendererFromAbstractComponentProps extends _$TestCustomRendererFromAbstractComponentProps with _$TestCustomRendererFromAbstractComponentPropsAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const PropsMeta meta = $metaForTestCustomRendererFromAbstractComponentProps;
}

// ignore: mixin_of_non_class, undefined_class
class TestCustomRendererFromAbstractComponentState extends _$TestCustomRendererFromAbstractComponentState with _$TestCustomRendererFromAbstractComponentStateAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const StateMeta meta = $metaForTestCustomRendererFromAbstractComponentState;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2019 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.

part of prop_tyepdef_test_fixtures;

@Factory()
UiFactory<TestCustomRendererComponentProps> TestCustomRendererComponent =
// ignore: undefined_identifier
$TestCustomRendererComponent;

@Props()
class _$TestCustomRendererComponentProps extends UiProps {
CustomRenderFunction customRenderer;
CustomRenderFunction<TestCustomRendererComponentProps,
TestCustomRendererComponentState,
TestCustomRendererComponentComponent> parameterizedCustomRenderer;
String somePropKey;
String someInitialStateKeyValue;
}

@State()
class _$TestCustomRendererComponentState extends UiState {
String someStateKey;
}

@Component()
class TestCustomRendererComponentComponent
extends UiStatefulComponent<TestCustomRendererComponentProps, TestCustomRendererComponentState> {
@override
Map getInitialState() => (newState()..someStateKey = props.someInitialStateKeyValue);

@override
render() {
return Dom.div()(
props.customRenderer(props, state, this),
props.parameterizedCustomRenderer(props, state, this),
);
}
}

// ignore: mixin_of_non_class, undefined_class
class TestCustomRendererComponentProps extends _$TestCustomRendererComponentProps with _$TestCustomRendererComponentPropsAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const PropsMeta meta = $metaForTestCustomRendererComponentProps;
}

// ignore: mixin_of_non_class, undefined_class
class TestCustomRendererComponentState extends _$TestCustomRendererComponentState with _$TestCustomRendererComponentStateAccessorsMixin {
// ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value
static const StateMeta meta = $metaForTestCustomRendererComponentState;
}
59 changes: 59 additions & 0 deletions test/over_react/component/prop_typedefs_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2019 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.

@TestOn('browser')
library prop_typedefs_test.dart;

import 'package:test/test.dart';
import 'package:over_react_test/over_react_test.dart';
import './fixtures/prop_typedef_fixtures.dart';

main() {
// Regression tests for https://github.com/dart-lang/sdk/issues/38880
group('CustomRenderFunction typedef', () {
TestJacket jacket;

tearDown(() {
jacket = null;
});

void sharedTest() {
final customRendererContainerNode =
queryByTestId(jacket.getInstance(), 'customRendererContainer');
expect(customRendererContainerNode, isNotNull, reason: 'test setup sanity check');
final parameterizedCustomRendererContainerNode =
queryByTestId(jacket.getInstance(), 'parameterizedCustomRendererContainer');
expect(parameterizedCustomRendererContainerNode, isNotNull, reason: 'test setup sanity check');

expect(customRendererContainerNode.text, 'props.somePropKey: foo \nprops.someStateKey: bar');
expect(parameterizedCustomRendererContainerNode.text, 'props.somePropKey: foo \nprops.someStateKey: bar');
}

test('works as expected when the custom render prop is defined in a concrete class', () {
jacket = mount((TestConsumingCustomRendererComponent()
..propKeyValueToTest = 'foo'
..stateKeyValueToTest = 'bar'
)());
sharedTest();
});

test('works as expected when the custom render prop is defined in an abstract class', () {
jacket = mount((TestConsumingAbstractCustomRendererComponent()
..propKeyValueToTest = 'foo'
..stateKeyValueToTest = 'bar'
)());
sharedTest();
});
});
}
2 changes: 2 additions & 0 deletions test/over_react_component_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import 'over_react/component/abstract_transition_test.dart' as abstract_transiti
import 'over_react/component/dom_components_test.dart' as dom_components_test;
import 'over_react/component/error_boundary_test.dart' as error_boundary_test;
import 'over_react/component/prop_mixins_test.dart' as prop_mixins_test;
import 'over_react/component/prop_typedefs_test.dart' as prop_typedefs_test;
import 'over_react/component/resize_sensor_test.dart' as resize_sensor_test;


Expand All @@ -39,5 +40,6 @@ void main() {
error_boundary_test.main();
dom_components_test.main();
prop_mixins_test.main();
prop_typedefs_test.main();
resize_sensor_test.main();
}