Skip to content

#1477 Add Support for nested path with Joi.object().or(), .nand(), .and(), .with(), .without(), .xor()#1554

Merged
Marsup merged 12 commits intohapijs:v14from
BolajiOlajide:ft-add-support-for-nested-objects
Sep 29, 2018
Merged

#1477 Add Support for nested path with Joi.object().or(), .nand(), .and(), .with(), .without(), .xor()#1554
Marsup merged 12 commits intohapijs:v14from
BolajiOlajide:ft-add-support-for-nested-objects

Conversation

@BolajiOlajide
Copy link
Contributor

What Does This PR Do?

Add Support for nested path with Joi.object().or()

Description Of Task To Be Completed

Add Support for nested path with Joi.object().or()

Any Background Context You Want To Provide?

Check this out

How can this be manually tested?

N/A

What are the relevant github issues?

#1477

Screenshot(s)

N/A

if (Object.prototype.hasOwnProperty.call(parent, peer) &&
parent[peer] !== undefined) {
const splitPeers = peer.split('.');
const keysExist = Utils.objHasKeys(parent, splitPeers);
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can certainly use Hoek.reach to achieve the same thing instead of creating your own.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh! I'll check it out and update the PR. Thanks @Marsup

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done @Marsup

@dhm116
Copy link

dhm116 commented Aug 3, 2018

The logic

if (Object.prototype.hasOwnProperty.call(parent, peer) &&
            parent[peer] !== undefined) {

is repeated 4 times in lib/types/object/index.js as well as

if (!Object.prototype.hasOwnProperty.call(parent, peer) ||
            parent[peer] === undefined) {

being repeated twice.

Does it really only make sense to support the nested syntax only for .or() given so many other methods share (and could benefit from) the same syntax? #1553 was another request for nested paths in additional methods.

I am eagerly awaiting this feature for .xor(), so I was a little disappointed to see that this PR only resolved this problem for .or().

@Marsup
Copy link
Collaborator

Marsup commented Aug 3, 2018

Don't worry I won't merge it until all are supported, baby steps… 🙂

@BolajiOlajide
Copy link
Contributor Author

I'm working on it. I'll implement the change for other methods.

@BolajiOlajide BolajiOlajide changed the title [ISSUE #1477] Add Support for nested path with Joi.object().or() [ISSUE #1477] Add Support for nested path with Joi.object().or(), .nand(), .and(), .with(), .without(), .xor() Aug 4, 2018
@BolajiOlajide
Copy link
Contributor Author

All done! @Marsup @dhm116

Kindly review!

@dhm116
Copy link

dhm116 commented Aug 5, 2018

This looks great - exactly what I was hoping for!

The only concern I would have, which comes from my own fiddling, would be the incompatibilities that arise around scenarios regarding the usage of labels, like in the it('should apply labels'... tests from the with(), without(), or(), and() and nand() scenarios.

I believe with the current implementation, if you duplicate the should apply labels tests but use the nested peer syntax, the test would fail - I could be wrong, it was pretty late at night!

@BolajiOlajide
Copy link
Contributor Author

True @dhm116 ... Just tried it out now and the tests failed.

I haven't used labels before but I'll look into its usage and see how to fix this.

@BolajiOlajide
Copy link
Contributor Author

It's tricky with labels for nested objects. I'd appreciate some help here.

@dhm116
Copy link

dhm116 commented Aug 5, 2018

This probably needs to be cleaned up a bit, but this seems to pass the tests now - BolajiOlajide/joi@ft-add-support-for-nested-objects...dhm116:ft-add-support-for-nested-objects

internals.keysToLabels = function (schema, keys) {

    const children = schema._inner.children;

    if (!children) {
        return keys;
    }

    const findNestedLabel = function (key) {

        const [parentKey, ...parts] = key.split('.');
        const childKeys = parts.join('.');
        const matchingChild = children.find((child) => child.key === parentKey);
        const label = matchingChild ? internals.keysToLabels(matchingChild.schema, childKeys) : key;

        return !key.endsWith(label) ? label : key;
    };

    const findLabel = function (key) {

        if (key.includes('.')) {
            return findNestedLabel(key);
        }
        const matchingChild = children.find((child) => child.key === key);
        return matchingChild ? matchingChild.schema._getLabel(key) : key;
    };

    if (Array.isArray(keys)) {
        return [].concat(keys.map(findLabel));
    }

    return findLabel(keys);
};

You could either clean this up (after @Marsup weighs in) and update your PR, or I can submit a PR to your branch.

@BolajiOlajide
Copy link
Contributor Author

Let's wait for @Marsup to weigh in. Once he's approved, A PR submitted to my branch would be great.

@Marsup
Copy link
Collaborator

Marsup commented Aug 5, 2018

Try that see if it works:

--- i/lib/types/object/index.js
+++ w/lib/types/object/index.js
@@ -767,8 +767,8 @@ internals.keysToLabels = function (schema, keys) {
 
     const findLabel = function (key) {
 
-        const matchingChild = children.find((child) => child.key === key);
-        return matchingChild ? matchingChild.schema._getLabel(key) : key;
+        const matchingChild = schema._currentJoi.reach(schema, key);
+        return matchingChild ? matchingChild._getLabel(key) : key;
     };
 
     if (Array.isArray(keys)) {

@BolajiOlajide
Copy link
Contributor Author

Thanks @Marsup . That works.

I'll refactor and add more tests and push in a few minutes.

@dhm116
Copy link

dhm116 commented Aug 5, 2018

I've submitted https://github.com/BolajiOlajide/joi/pull/1 based upon @Marsup's beautiful simplification, which produces the following test results:

1123 tests complete
Test duration: 3341 ms
Assertions count: 21153 (verbosity: 18.84)
No global variable leaks detected
Coverage: 100.00%
Linting results: No issues

@BolajiOlajide
Copy link
Contributor Author

Hey @Marsup ,

I've merged @dhm116's PR, I think this PR is good now.

@Marsup Marsup self-assigned this Aug 6, 2018
@Marsup Marsup added feature New functionality or improvement breaking changes Change that can breaking existing code labels Aug 6, 2018
@Marsup Marsup changed the base branch from master to v14 August 6, 2018 15:03
@Marsup
Copy link
Collaborator

Marsup commented Aug 6, 2018

It looks alright, just missing the docs. I changed the base branch as it's going to be a breaking change.

@Marsup Marsup added this to the 14.0.0 milestone Aug 6, 2018
@BolajiOlajide
Copy link
Contributor Author

What do I need to do @Marsup ?

@Marsup
Copy link
Collaborator

Marsup commented Aug 6, 2018

Actually let me think about that one, it's looking more and more like we could refs instead of plain strings.

@Marsup Marsup force-pushed the v14 branch 2 times, most recently from dd7c4ec to 11afe35 Compare August 8, 2018 10:03
@BolajiOlajide
Copy link
Contributor Author

Hey @Marsup ,
What's the status of this PR?

@BolajiOlajide BolajiOlajide changed the title [ISSUE #1477] Add Support for nested path with Joi.object().or(), .nand(), .and(), .with(), .without(), .xor() #1477 Add Support for nested path with Joi.object().or(), .nand(), .and(), .with(), .without(), .xor() Sep 6, 2018
@Marsup Marsup force-pushed the v14 branch 3 times, most recently from 6c672b8 to 6aedbb2 Compare September 10, 2018 14:54
@Marsup Marsup merged commit 466d9e5 into hapijs:v14 Sep 29, 2018
@Marsup
Copy link
Collaborator

Marsup commented Sep 29, 2018

Thanks a lot!

@Marsup Marsup mentioned this pull request Oct 14, 2018
@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

breaking changes Change that can breaking existing code feature New functionality or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants