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

test: Flow definitions #97

Closed
wants to merge 2 commits into from
Closed

test: Flow definitions #97

wants to merge 2 commits into from

Conversation

DianaSuvorova
Copy link
Collaborator

@DianaSuvorova DianaSuvorova commented Jul 30, 2018

This is going to fail there is 12 more flow errors to fix.
All of them are related to usage of getComponent.

@nadiia , @schnerd
Sometimes it is called with null as second argument - if this appropriate usage ofgetComponent function? if so we need to update typing of it.

Sometimes styletron adds to confusion - I will look into those cases.

@DianaSuvorova DianaSuvorova changed the title test: mocking react component for override test test: Flow definitions Jul 30, 2018
? $theme.borders.radius300
: '0px',
boxShadow: $theme.lighting.shadow600,
backgroundColor: $theme && $theme.colors.background,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

React context props are not enforceable So it has to be conditional. I wish we could use optional chaining but storybook doesn't support babel 7 yet.

@@ -39,9 +44,7 @@ test('Helpers - Overrides - getOverrideProps', () => {
});

test('Helpers - Overrides - toObjectOverride', () => {
const CustomComponent = jest.fn();
expect(toObjectOverride()).toBeUndefined();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

based on flow types of this fnc it takes override: OverrideT<T> as an argument. So can't be called with null or undefined. We need to either remove tests or update types.

@@ -150,7 +150,8 @@ export type SharedStylePropsArgT = {
};

export type SharedStylePropsT = SharedStylePropsArgT & {
$theme: ThemeT,
$theme?: ThemeT,
Copy link
Contributor

Choose a reason for hiding this comment

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

$theme should not be optional here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it is coming from context. If it is then:

I mentioned this above: React context props are not enforceable So it needs to be optional.

Do you see any other alternatives?

Copy link
Contributor

Choose a reason for hiding this comment

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

At the level of a styled component $theme comes from props.

Copy link
Contributor

@schnerd schnerd Jul 31, 2018

Choose a reason for hiding this comment

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

Yeah even if context props are not enforceable, it seems like we can guarantee that our style functions will always receive a theme (if user doesn't specify a theme provider their page would be broken anyway). So ideally we should still type our style functions having $theme as required so we don't need to have null checks everywhere.

@@ -17,9 +19,20 @@ export function getComponent<T>(
defaultComponent: React.ComponentType<T>,
): React.ComponentType<T> {
if (override && typeof override === 'object') {
return override.component || defaultComponent;
if (
typeof override.component === 'object' &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this check here? Also, a component override would be a function type.

(override.component instanceof React.StatelessFunctionalComponent ||
override.component instanceof React.Component)
) {
return override.component;
Copy link
Contributor

Choose a reason for hiding this comment

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

Even though these are used to refine the type, won't these still be called at runtime? override.component should either be a function or a class, it's not actually an instance of either of these things. And React.StatelessFunctionalComponent is not a actually a thing you can use in instanceof, it's a type, hence why unit-tests fail on this PR:

TypeError: Right-hand side of 'instanceof' is not an object

      28 |     }
      29 |   } else if (
    > 30 |     override instanceof React.StatelessFunctionalComponent ||
         |     ^
      31 |     override instanceof React.Component
      32 |   ) {
      33 |     return override;

I'm pretty sure we actually uncovered a bug in flow with this function that makes it difficult to type correctly, see facebook/flow#6666

I'll play around with some alternatives here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Took a stab at it: #98

@DianaSuvorova
Copy link
Collaborator Author

@schnerd , has addressed this in #98

@gergelyke gergelyke deleted the overrideTest branch September 19, 2018 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants