-
Notifications
You must be signed in to change notification settings - Fork 109
**Feature:** Add support for validators that are promise-based or throw errors #72
Conversation
.gitignore
Outdated
@@ -93,6 +93,7 @@ typings/ | |||
public | |||
lib | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this change from this PR.
src/Get.tsx
Outdated
try { | ||
if (resolve) { | ||
const resolvedDataOrPromise: TData | Promise<TData> = resolve(data); | ||
resolvedData = (resolvedDataOrPromise as { then?: any }).then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reasoning behind this type assertion? Tbh it looks a little messy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to get it to type-check any other way - looks like detecting whether something is a promise or a function is not that straightforward to follow by the compiler. Do you have any idea how this could improve?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can pair up on it. I'd love to understand the complexity more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolveData = await Promise.resolve(resolve(data)) // return a TData
👼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome - I managed to confirm via the parcel example that the new features are working, now it's just a matter of cleaning up the code.
example/README.md
Outdated
@@ -0,0 +1,3 @@ | |||
This is a simple live demo of `restul-react` components primarily used to test features. | |||
|
|||
Run it by getting a global Parcel by running `npm i -g parcel`, then running `parcel example/index.html` from root. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can add parcel as a devDependency and it should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right, makes sense :)
21341d9
to
7e54f91
Compare
src/Get.test.tsx
Outdated
</RestfulProvider>, | ||
); | ||
|
||
await wait(() => expect(children.mock.calls.length).toBe(1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, we have the children call 1 time, but what is the expected behaviour? having an error? some data? anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Might make more sense to make the test a little more expressive.
src/Get.tsx
Outdated
try { | ||
if (resolve) { | ||
const resolvedDataOrPromise: TData | Promise<TData> = resolve(data); | ||
resolvedData = (resolvedDataOrPromise as { then?: any }).then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolveData = await Promise.resolve(resolve(data)) // return a TData
👼
src/Get.tsx
Outdated
} catch (err) { | ||
resolvedData = null; | ||
resolveError = { | ||
message: "RESOLVE_ERROR", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this message in any test, can you add a test for this?
@@ -0,0 +1 @@ | |||
This is a simple live demo of `restul-react` components primarily used to test features. Run it with `npm run example`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have codesandbox examples and unit tests. If you can avoid to introduce something else to maintain… And I'm sorry but this is not replacing unit tests. I can help you to add the correct unit tests for this feature if needed but please remove this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a dev-server
kind of like in @operational/components
. It doesn't really add much bloat to the library. It's just an on-device, in-browser player like GraphiQL. Ideally, we don't maintain this but make sure our features work in a browser context.
I think the tests:
- should be maintained
- add a lot of value
but, there is no guarantee that they work 100% in a browser environment with calls to real APIs. This will serve as a check we do during development to make sure things work before pushing.
I don't really see any major costs to having this around. Do you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peterszerzo he does have a point though – we should ideally add unit tests for the resolve
behavior as well. I'm happy to add these if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see this more as an integration test as opposed to a unit test - it makes sure that a real request can be made, goes through the state management, and renders something in the end. Which is something I am not confident a unit test suite would catch, especially after a feature this complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't dispute the need for improving the tests for the new resolve
- I just don't feel comfortable shipping this feature without validating it with an end-to-end example. This could even grow to be like the visual test cases suite in https://github.com/contiamo/operational-visualizations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And at this library stage, I'm not agree with you, we must have unit tests for every features. Without tests, we can't be sure that the functionally works as expected, it's hard to maintained and everybody can broke the feature by mistake (and by everybody, I include myself of course).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm maybe a bit strict on this stack, but all our product depends on this library 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just worry about the "it's works on my little example, let's skip the tests for now" 😉
As long as we have you on the team, I am confident that this will never happen. 😉 Let's also look at making the examples richer and exportable to CodeSandbox (thanks, by the way, @CompuIves) at a later stage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabien0102 we don't have to merge until we have a satisfactory test suite, and that would have been the case whether we had the example server or not. Both methods of testing are good for reliability and for catching issues that can bubble up in dependent projects - there is no reason to jump against one of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peterszerzo I agree that both methods of testing are good in the context of a PR, but our goal is to have a maintainable product in the long term. For this purpose, unit tests ensure a non regression in the future, it's automated in the CI, etc etc... So no, both methods of testing are not equal in this case.
The unit tests have been added, testing both validation succeeds and failures in the runtime error and promise cases. |
7b3ff91
to
e5b1c61
Compare
I have some questions/remarks about this PR:
|
I'm not sure this needs to be a discussion/rfc. It adds value to this and future PRs by adding an extra layer of validation in a browser environment that is a nice complement to the already great suite of unit tests we have. Are there concrete concerns about the dev server that you have? Maybe we can have a shorter discussion about them here. 🙂 I get that it's not the scope of this PR, but it does help us test this PR and so for that reason, I think it's quite alright to leave it in here. |
For me it's not an extra layer of validation, it's more code to maintained, for a ui library, I want to say why not, but in our case, we don't have any browser specificities. If it's works in unit tests, it's works in the browser (if not, I want a concrete example where it's not the case 😉) It's also not helping to test the PR, with unit tests we have travis that ensure that everything is working, with dev server, we need to pull locally, start |
@fabien0102 some thoughts on your comments:
|
@peterszerzo Perfect, I let you rebase and fix the |
In response to this,
I think we have different thoughts behind how this will be used. The way I see it, this code will not be maintained because no part of it is public. Rather, I see it:
I think it's nice to have this as part of the "to test" list that goes into a PR for some cases that need more thorough integration testing, for the lifetime and purpose of validating their containing PR only. I don't see much of a cost here for having this around. It's kind of like an appendix: it doesn't do much, it isn't included in the distributed package on npm, it has no measurable cost to our users, but can and does add value to our team as we develop features that might need more reassurance.
This is a very bold statement that I would carefully consider. Are you sure about this? There are enforcements that usually surprise us in browsers even today: invalid/non-existent TLS, HSTS, CORS, and CORB that I'm not sure our unit tests would catch using |
Some additional findings on the need of for promise-based validation: I tried synchronously validating some schemas yesterday with |
b1b6a00
to
c57c921
Compare
I would factor out that default resolve into another file, but besides that I don't see any major gotchas. |
@TejasQ it's in |
@peterszerzo Can your |
413cada
to
086f94a
Compare
Why
This PR fixes #57, adding support for validators that either throw runtime errors or work through a promise, extending the support for libraries like
yup
.Open questions
Errors
The errors coming from this validation are standard and can produce anything, so they don't fit into the
{ message: string, data: TError | string }
interface - so as a first pass, I am passing aRESOLVE_ERROR
string as message so it is easily recognizable, and stringifying the actual error insidedata
- which the end user would have to parse back into JSON later. Wonder if there is a better way to deal with this.