-
Notifications
You must be signed in to change notification settings - Fork 9
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
Examples[childSchema.type] is not a constructor #116
Comments
Not sure if this deserves a mention, but if I try this: 'use strict';
const Felicity = require('felicity');
const ProbeSchema = require('./path');
const FelicityProbeConstructor = Felicity.entityFor(ProbeSchema);
const probeInstance = new FelicityProbeConstructor();
console.log(probeInstance.example()); I get an even larger error: /Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:615
const child = new Examples[childSchema.type](childSchemaRaw, childOptions);
^
TypeError: Examples[childSchema.type] is not a constructor
at Object.keys.forEach (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:615:31)
at Array.forEach (native)
at ObjectExample._generate (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:591:53)
at ObjectExample.generate (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:36:21)
at valueGenerator (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:878:20)
at Object.exampleGenerator [as example] (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/exampleGenerator.js:10:27)
at Object.<anonymous> (/Users/danielo/GIT/case-supermodels/.bin/populateDb.js:9:22)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
agent:case-supermodels danielo$ node .bin/populateDb.js
/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:615
const child = new Examples[childSchema.type](childSchemaRaw, childOptions);
^
TypeError: Examples[childSchema.type] is not a constructor
at Object.keys.forEach (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:615:31)
at Array.forEach (native)
at ObjectExample._generate (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:591:53)
at ObjectExample.generate (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:36:21)
at valueGenerator (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/helpers.js:878:20)
at exampleGenerator (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/exampleGenerator.js:10:27)
at getExample (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/index.js:52:16)
at Constructor.example (/Users/danielo/GIT/case-supermodels/node_modules/felicity/lib/index.js:91:20)
at Object.<anonymous> (/Users/danielo/GIT/case-supermodels/.bin/populateDb.js:9:27)
at Module._compile (module.js:571:32) |
Unfortunately for now, yes. What extension/extended types are your schema using? Just out of curiosity ;) If you do have some extended |
I'm using both. For example I have one What is exactly the barrier? By my experience joi extend is just adding types based on existing ones. |
The barrier for Felicity is knowing how to generate random data that matches the type. Or for I'm toying around with a Joi-like extension point where you can provide the extended type and a function that generates valid data for that type. I haven't tried building it out yet though. Hopefully soon. |
Isn't that kind of information reported by describe ? If not, then I think it should be describe responsibility to provide such interface to extensions. |
Yeah, Felicity is driven completely by For example, using the joi-date-extensions extended Joi. You hand Felicity.example With the track I'm thinking about, you would extend Felicity by providing something like (completely making this format up on the spot): {
schema: Joi.date().format(),
example: (randomBaseType) => {
const moment = new Moment(randomBaseType);
const targetFormat = Array.isArray(schemaDescription.flags.momentFormat) ?
pickRandomFromArray(schemaDescription.flags.momentFormat) :
schemaDescription.flags.momentFormat;
return moment.format(targetFormat);
}
} |
How does felicity create random values based on regular expressions? What if each extension includes a regular expression on its description that can be used by felicity to generate random values? Another alternative would be to allow a special property on the description specific for felicity. Since Felicity is the only project providing this great functionalities to Joi I feel that Joi should create some specific hooks for it. I really thank that just one extension should be provided, the one that is given to Joi. If you have to make sure that you inject to Felicity all the same extensions that were injected to Joi we will suffer a lot, I promise you. If all you get is a Joi instance, you have no idea of how was it extended, and you will end on a code-split situation, where you have to maintain the Joi extension, the felicity extension and make sure you inject both on every place. |
With the randexp library :)
Nah, not going to pollute Joi in support of Felicity. We are making the
Yeah, that would be ideal! Haha. If you think of a way to make it happen, I'm all ears. I've been thinking this through for the better part of a year now.
I agree completely. It's not an ideal situation, but it would allow you to do what you were trying to do in opening this issue in the first place. If I can get a workable solution in then it will allow me to get a more complete picture of the problem set in order to devise a more complete and ideal version 2 (or 3) implementation. :D |
I have been thinking about this. I don't know why this error happens. I can understand that felicity will not be able to create a valid example for custom extension, but at least it should not break this way. There are other libraries that use joi descriptions to create examples ( hapi-swagger is an example). The worst that happened to me it's that instead of a valid example they just write the type. In my case, I have a custom type which is URL, based on string, what happy-swagger prints it's
This will only apply for the extensions. As far as I know (because it is poorly documented) the extensions have the chance to add stuff to their own description. The extensions that want to support felicity could include certain information there specific for felicity. I don't see the problem here because the extension author will be forced to create a felicity extension anyway, better do it on a single place. |
I agree. Working on that currently. Hoping to have a patch up in the next few days ;)
Ah, gotcha. Yeah, I'm totally fine with that approach. I thought you meant adding a |
Sorry, not sure to understand 😕 I mean something like: Joi.customType().describe()
{ type: 'string', invalids: [ '' ] , generate: (something) => somethingelse } The problem is that describe is supposed to return something serializable, while a function it is not. But since it is not documented, I don't see the problem 😄 |
We are going to be adding support for |
@danielo515 - I opened up a PR for a basic fallback implementation for extensions. If you don't mind, would you check out that branch and see if it fixes the TypeError you were seeing with your extension? If it does, or if I don't hear back in a couple of days, I'll go ahead and publish as a patch while I work on proper extensions support. |
I'll try to rest it tomorrow and report back. Many thanks |
Hello @WesTyler I'm still getting the same error: const ProbeSchema = joi.object({url: joi.url()}) // url is part of my extension, and is of type url
console.log(Felicity.example(ProbeSchema));
TypeError: Examples[childSchema.type] is not a constructor
at Object.keys.forEach (/Users/danielo/programmingTest/felicity/lib/valueGenerator.js:616:31)
at Array.forEach (native)
at ObjectExample._generate (/Users/danielo/programmingTest/felicity/lib/valueGenerator.js:592:53)
at ObjectExample.generate (/Users/danielo/programmingTest/felicity/lib/valueGenerator.js:37:21)
at valueGenerator (/Users/danielo/programmingTest/felicity/lib/valueGenerator.js:827:20)
at Object.exampleGenerator [as example] (/Users/danielo/programmingTest/felicity/lib/exampleGenerator.js:9:27)
at repl:1:22
at ContextifyScript.Script.runInThisContext (vm.js:23:33)
at REPLServer.defaultEval (repl.js:336:29)
at bound (domain.js:280:14) |
Eff. Any chance you could send me a gist with your extension? I haven't been able to write an extension that fails on this branch... |
Sure. |
No matter how you author an extension, if it works with Joi it shouldn't throw TypeErrors here :) Thanks for working with me on this! |
Here you have an example that fails: https://gist.github.com/danielo515/32e78441e900440f7350db81bca8fa0a Many thanks |
Ok great, I'll try to get something like that worked into the tests. Thanks for sharing that over! |
Ahhhh hahaha okay this is easy. I made the change in the wrong spot, so my fallbacks didn't work for children :P . My bad. Should have an update on this branch shortly. |
Should be good to go now. |
Hello @WesTyler I tried the new version of Felicity with my base example and it now works. If you take a look at the description output of my example, it provides an array of valid values. However, instead of picking one, you are returning a random string. I can understand that it can be tricky to manage some situations, but this one (where a valids array is present) should be an easy one, and an oportunity to make many joi extensions compatible with Felicity with no effort. For example, if you are an author extension that just validates an string with a list of possible values, then you just have to provide a valid description and you're done. Regards |
I think Felicity will currently use a value in the const allowOnly = Joi.object().keys({
strict: Joi.string().valid(['option1', 'option2'])
});
const allowNull = Joi.object().keys({
permissive: Joi.string().allow(null)
});
Felicity.example(allowOnly);
/*
strict will "randomly" be either option1 or option2
{
strict: 'option1'
}
*/
Felicity.example(allowNull);
/*
If we always use a random value from "valids" (Previous behavior through v2.0.0)
permissive will always be null. Not ideal.
{
permissive: null
}
*/
/*
If we sometimes use a random value from "valids" (current behavior as of v2.1.0)
permissive will only sometimes be null.
{
permissive: 'ahjhkegi739ugq9'
}
*/ |
Perhaps I can default Felicity to always use |
Actually, I like that better. I'll open up a separate ticket for that switch in default behavior. Is there anything remaining on this issue for super-basic extension support? If not, I'll merge that PR and close this. More extensive extension support per discussions above will follow, this resolution will be to simply prevent |
Hello @WesTyler Regards |
Context
What are you trying to achieve or the steps to reproduce ?
I'm trying to generate an example from a joi schema. Something as simple as this
But I'm getting the following error:
What result did you expect ?
I expect an auto generated example, of course 😄
What result did you observe ?
Instead I get an error.
I think this may be related with #80
Is felicity unable to generate examples from extended Joi instances?
Regards
The text was updated successfully, but these errors were encountered: