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

Add array validators #20

Merged
merged 6 commits into from
Nov 4, 2017
Merged

Add array validators #20

merged 6 commits into from
Nov 4, 2017

Conversation

SamVerschueren
Copy link
Collaborator

This PR is work in progress. Feedback in the meantime is always welcome.

@sindresorhus
Copy link
Owner

Perfect so far.

@SamVerschueren SamVerschueren mentioned this pull request Nov 2, 2017
87 tasks
@SamVerschueren SamVerschueren changed the title [WIP] Add array validators Add array validators Nov 2, 2017
*
* @param searchElement The value that should be the start of the array.
*/
startsWith(searchElement: any) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is what you meant, right? Also endsWith.

Currently, this only works for primitive values. Should we use deepStrictEqual as validator function?

Copy link
Owner

Choose a reason for hiding this comment

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

No, it should just test identity, so primitive values or same instance of objects, like it does now. We should mention this though.

Like:

The value is tested by identity, not structure

Or something better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can't really come with anything better for now.

*
* @param searchElement The value that should be the end of the array.
*/
endsWith(searchElement: any) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same comment as startsWith

includes(...searchElements: any[]) {
return this.addValidator({
message: value => `Expected array to include all elements of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
validator: value => searchElements.every(el => value.indexOf(el) !== -1)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we want deep equality, we should write a custom validator.

Copy link
Owner

Choose a reason for hiding this comment

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

Same as my other comment. Should test identity.

includesAny(...searchElements: any[]) {
return this.addValidator({
message: value => `Expected array to include any element of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
validator: value => searchElements.some(el => value.indexOf(el) !== -1)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same comment as includes.

deepEqual(expected: any[]) {
return this.addValidator({
message: value => `Expected array to be deeply equal to \`${JSON.stringify(expected)}\`, got \`${JSON.stringify(value)}\``,
validator: value => deepStrictEqual(value, expected)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Used deepStrictEqual. Should we use deepEqual instead?

Copy link
Owner

Choose a reason for hiding this comment

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

No, should be strict.

Copy link
Owner

Choose a reason for hiding this comment

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

Let's use https://www.npmjs.com/package/lodash.isequal instead. It's better.

*
* @param predicate The predicate that should be applied against every individual item.
*/
ofType<T>(predicate: Predicate<T>) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure if the implementation is correct.

ofType(type, …) (Accepts any is.x type) (TODO: Would be useful if this could also support any ow predicate for each element, so you could do: ow.array.ofType(ow.string.minLength(5)))

I think I implemented what you described as TODO. Not sure what the initial goal was of ofType because it looks like it accepts multiple arguments.

Copy link
Owner

Choose a reason for hiding this comment

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

This is exactly what I had in mind :)

@@ -0,0 +1,69 @@
import test from 'ava';
import * as m from '..';
Copy link
Owner

Choose a reason for hiding this comment

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

Why are we doing * as m? Shouldn't ow be a default export?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because of interoperability with CommonJS. Otherwise, CJS import should be done as const ow = require('ow').default. I didn't find a way yet in TS to support both.

Copy link
Owner

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The thing is that the type definition marks it as default export. Meaning, if you would write the following JavaScript

const ow = require('ow');

Only ow.default will show up as intellisense, because it is a default export. Currently, webpack just exports this as module.exports, even when you would mark it as export default, so that's not really a problem. The problem lies in the type definitions.

Copy link
Owner

@sindresorhus sindresorhus Nov 3, 2017

Choose a reason for hiding this comment

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

I didn't realize the type definitions worked even with JS, but I think it's an ok compromise (to do default export). This way it's correct for TS and ES2015 modules, and for CommonJS it still works, but Intellisense outputs the incorrect thing. Better to optimize for the future. Thoughts?

@@ -1,4 +1,4 @@
import * as deepStrictEqual from 'deep-strict-equal';
import * as isEqual from 'lodash.isequal';
Copy link
Owner

Choose a reason for hiding this comment

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

Isn't the point of

"allowSyntheticDefaultImports": true,
that we can use default import even when there's only module.export?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Jup, you're right!

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'll use the import isEqual right here and will change all the others in a different PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Apparently it doesn't. I thought it was, but it's not working. It tries to access isEqual.default... Have to investigate this further.

Copy link
Collaborator Author

@SamVerschueren SamVerschueren Nov 4, 2017

Choose a reason for hiding this comment

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

Apparently, allowSyntheticDefaultImports doesn't change the code that is being emitted, hence the description.

Allow default imports from modules with no default export. This does not affect code emit, just typechecking.

More info: microsoft/TypeScript#7518. So actually, we can remove that option is it has no use (for now).

Copy link
Owner

Choose a reason for hiding this comment

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

I see... Let's remove it then.

@SamVerschueren
Copy link
Collaborator Author

Removed the flag. Something else I need to cover?

@sindresorhus sindresorhus merged commit 3306c69 into master Nov 4, 2017
@sindresorhus sindresorhus deleted the array-predicate branch November 4, 2017 13:32
@sindresorhus
Copy link
Owner

5fa79994-b5ee-11e3-9a4d-b19557d7480b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants