sylvainpolletvillard / ObjectModel

Strong Dynamically Typed Object Modeling for JavaScript
http://objectmodel.js.org
MIT License
467 stars 30 forks source link

Imported BasicModel does not function as expected #105

Closed fpw23 closed 5 years ago

fpw23 commented 5 years ago

Having trouble with defining models outside of my module, importing them in and using them. Maybe I don't fully understand but I thought if I define an export in one file and import that into another file I should get the same value. Here is my issue, I created custom basic models in one module:

image

I try importing the StringNotBlank const into another module. I use that as part of my model definition. I run the following test:

image

Firstname and Email pass without issues. Last name errors with "expecting LastName to be StringNotBlank, got String "test"".

image

if i change out the value of LastName in userData to match the imported value it works

image

image

Why does declaring a const within the same module act differently then the one I imported in from another module? How can I define common custom basicmodels and then use them in other modules?

sylvainpolletvillard commented 5 years ago

Hello,

I try to reproduce your issue here: https://codesandbox.io/s/j4vx5wmz35 but everything is working fine so far.

Can you provide a minimal reproduction code ?

fpw23 commented 5 years ago

Thanks for the quick reply! I will try to get a working example. Does it matter that I am using mocha and babel? I saw in other post you said ObjectModel requires ES6 environment

sylvainpolletvillard commented 5 years ago

Yes, ObjectModel v3 is using ES6 Proxies, so it won't work on environments that do not support Proxies. But Babel does not transpile Proxies (technically it can't), and the assertion library should not have any impact. However, it is possible that your build tooling configuration is the problem. Are you using Webpack ?

fpw23 commented 5 years ago

No, the screen shots from above are just using mocha

mocha --require babel-core/register --require babel-polyfill ./src/**/Schema.Tests.js --reporter spec --watch

In the code I am using import/export and async and await so it requires babel

sylvainpolletvillard commented 5 years ago

Can you try the code I use in the codesandbox with your setup, so that we can find out if the problem is in your tooling setup or in the code itself ?

fpw23 commented 5 years ago

ok, i got a test working that matches my environment

https://github.com/fpw23/MochaObjectModelTest

to run just clone, npm install, npm run test. Will see the error. To make it pass just follow this comment

sylvainpolletvillard commented 5 years ago

Weird... somehow babel-register is making the instanceof operator not working properly when importing from another module

console.log("obj.constructor === String", obj.constructor === String)
console.log("Object.getPrototypeOf(obj) === String.prototype", Object.getPrototypeOf(obj) === String.prototype)
console.log("obj instanceof String", obj instanceof String);

obj.constructor === String true Object.getPrototypeOf(obj) === String.prototype true obj instanceof String false

I'm afraid this is a bug/limitation in babel, and there is nothing I can do on the library to fix that :( But I'm curious to know what exactly happens here

fpw23 commented 5 years ago

Ok, what I may try is upgrading to babel 7 and see if that makes a difference, will let you know. Thanks for all the help!

sylvainpolletvillard commented 5 years ago

Don't bother, I just tried that and it doesn't fix it

fpw23 commented 5 years ago

Doh! well my one last question then, I tried taking babel out of mocha so I could see the raw results and this is what I got for the Schema.Test.js file image

image

and here is the raw code for the Schema.js

image

All there lines look the same, the two within the module work but the one imported in does not. Does the way it has "var StringNotBlank = exports.StringNotBlank =" in front of the function make a difference?

sylvainpolletvillard commented 5 years ago

I noticed this:

var _Schema = require('./Schema');
var _objectModel = require('objectModel');
console.log(_Schema.StringNotBlank instanceof _objectModel.Model) // false ????

Maybe it's because objectmodel is required twice, they don't share the same reference to Model ?

sylvainpolletvillard commented 5 years ago

lol this is stupid

https://github.com/fpw23/MochaObjectModelTest/blob/master/src/Core/Schema.Tests.js#L5

Replace objectModel with objectmodel and the test pass

While the filesystem lookup will return the same exact file because it's case insensitive, require's cache still treats the two cases as different modules. That's because it has to assume that it runs in a case sensitive environment, so there could actually be two different modules behind that.

going to sleep now 😴

fpw23 commented 5 years ago

Thank you! 👍 🥇 😄

I looked at this code all day yesterday and never noticed that.