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

feat(data-point): Normalize collection and hash type checking functionality #214

Merged
merged 12 commits into from
Feb 20, 2018

Conversation

raingerber
Copy link
Contributor

@raingerber raingerber commented Feb 14, 2018

closes #189

What: always use outputType for type checking hash and collection entities (before, they had custom validate functions)

Why: type checking is always done in the same place now, whether or not the user has provided a custom type check reducer

How:

  1. Refactored getTypeModifier to now process arrays (and renamed it to normalizeTypeCheckSource)
  2. hash#outputType always uses the isObject reducer, following by an optional custom reducer
  3. collection#outputType always uses the isArray reducer, following by an optional custom reducer
  4. Throw error when trying to use an invalid outputType for hash or collection (like string, number, etc)
  5. Reword the error message when type checking fails

Checklist:

  • Has Breaking changes
  • Documentation
  • Tests
  • Ready to be merged

@raingerber raingerber self-assigned this Feb 14, 2018
*/
function normalizeTypeCheckSource (source) {
if (Array.isArray(source)) {
return source.map(r => normalizeTypeCheckSource(r))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

hash and collection entities now pass arrays to this function

@@ -146,17 +146,17 @@ describe('ResolveEntity.resolveEntity', () => {
}

test('It should resolve entity', () => {
return resolveEntity('hash:asIs', 'foo').then(acc => {
return resolveEntity('model:asIs', 'foo').then(acc => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

using model:asIs instead of hash:asIs because these entities are not receiving objects

@@ -2,11 +2,14 @@ const Util = require('util')
const _ = require('lodash')
const utils = require('../utils')

function errorMessage (value, expectedType) {
const entityId = _.get(value, 'reducer.spec.id', 'value')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if this line was needed, but it looks like it expects value to be an accumulator, which is not the case

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling c673228 on raingerber:normalize-type-checking into e3a03c3 on ViacomInc:master.

@coveralls
Copy link

coveralls commented Feb 14, 2018

Coverage Status

Coverage remained the same at 100.0% when pulling d760652 on raingerber:normalize-type-checking into a366091 on ViacomInc:master.

@raingerber
Copy link
Contributor Author

raingerber commented Feb 15, 2018

I want to make a few changes to this, so I'm closing it for now.

@raingerber raingerber closed this Feb 15, 2018
@@ -2045,7 +2046,7 @@ If `params.inspect` is a `function`, you may execute custom debugging code to be

A Hash entity transforms a _Hash_ like data structure. It enables you to manipulate the keys within a Hash.

To prevent unexpected results, **Hash** can only process **Plain Objects**, which are objects created by the Object constructor. If [Hash.value](#hash-value) does not resolve to a Plain Object it will **throw** an error.
To prevent unexpected results, a **Hash** can only return **Plain Objects**, which are objects created by the Object constructor. If a hash resolves to a different type, it will throw an error. This type check occurs *before* the value is passed to the (optional) `outputType` reducer.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This rewording lost an important point: Hashes only process plain objects. Can we put that line back in somehow. (something like, "... a Hash can only accept and return Plain Objects...")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just double checked and hash can accept any type - it's only required to return an object, which is why I changed this wording.

with that said, do you think that hash should only accept objects as input? that might be a good idea

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, this test looks like it throws if the input to a hash is an array. Am I missing something?

https://github.com/ViacomInc/data-point/blob/master/packages/data-point/lib/entity-types/entity-hash/resolve.test.js#L33-L42

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that's throwing because the output is an array, not because of the input (I think the name of the test is a little misleading though, since it makes it sound like the input needs to be an array)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we can clean up that test in this PR too then? I always thought the input needed to be an object. The README and the test both read that way for me.

👍 on the rewording as is.

Regarding ensuring the input is an object, that might be better off in a separate PR. This is mostly refactoring the outputType, and that would introduce changes to a different lifecycle method. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sounds good, I do think we should make that change at some point though. I just checked and made sure the wording for the tests is updated in this PR (so it no longer has messages like entity.hash - only process Plain Objects)

@@ -2383,7 +2382,7 @@ A Collection entity enables you to operate over an array. Its API provides basic

Collection entities expose a set of reducers that you may apply to them: [map](#collection-map), [find](#collection-find), [filter](#collection-filter). These reducers are executed in a [specific order](#collection-reducers-order). If you want to have more control over the order of execution, use the [compose](#compose-reducer) reducer.

To prevent unexpected results, a **Collection Entity** can only process **Arrays**, if Collection.value does not resolve to an Array it will **throw** an error.
To prevent unexpected results, a **Collection** can only return arrays. If a collection resolves to a different type, it will throw an eror. This type check occurs *before* the value is passed to the (optional) `outputType` reducer.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similar to my comment on Hash, Collections accept and return arrays.

expect(acc).toHaveProperty('value', 'foo')
})
})

test('It should attach entityId to error', () => {
const rejectResolver = () => Promise.reject(new Error('test'))
return resolveEntity('hash:asIs', undefined, undefined, rejectResolver)
return resolveEntity('model:asIs', undefined, undefined, rejectResolver)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would this not work with the hash:asIs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you're right, it works either way. changed it back to hash:asIs

@raingerber raingerber reopened this Feb 15, 2018
paulmolluzzo
paulmolluzzo previously approved these changes Feb 15, 2018
Copy link
Collaborator

@paulmolluzzo paulmolluzzo left a comment

Choose a reason for hiding this comment

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

LGTM! Didn’t realize some things about these entity types before the README updates. 😅

expect(result).toMatchSnapshot()
})
}
test('should throw error from default outputType reducer when input is not valid', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't this be should throw error from default outputType reducer when output is not valid?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch - fixed this along with a similar mistake in entity-collection/resolve.test.js

Copy link
Collaborator

@paulmolluzzo paulmolluzzo left a comment

Choose a reason for hiding this comment

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

Nice! 👍

@acatl acatl merged commit d083cd1 into ViacomInc:master Feb 20, 2018
@raingerber raingerber deleted the normalize-type-checking branch February 26, 2018 20:19
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.

Use outputType for hash and collection validation
4 participants