Commit eb5b260e authored by nanahira's avatar nanahira

fix toJSON

parent cc65206b
......@@ -44,7 +44,12 @@ export function resolveSchemaType(schemaType: SchemaType): SchemaOrReference {
}
function applyOptionsToSchema(schema: Schema, options: SchemaClassOptions) {
Object.assign(schema.meta, options);
Object.assign(schema.meta, {
...options,
type: undefined,
dict: undefined,
array: undefined,
});
}
function getPropertySchemaFromOptions<PT>(
......@@ -177,7 +182,7 @@ const schemaFields: (keyof Schema)[] = [
];
const schemaFunctions: (keyof Schema)[] = [
'toJSON',
// 'toJSON',
'required',
'hidden',
'role',
......@@ -193,11 +198,11 @@ const schemaFunctions: (keyof Schema)[] = [
];
function applySchemaForClass<T>(
schema: Schema<Partial<T>, T>,
originalClass: ClassType<T>,
instance: T,
originalObject: Partial<T>,
) {
const schema = originalClass[GeneratedSym] as Schema<Partial<T>, T>;
const newRawObject = new schema(originalObject);
for (const key in schema.dict) {
const transformer = reflector.get('Transformer', originalClass, key);
......@@ -218,12 +223,12 @@ function applySchemaForClass<T>(
export function SchemaClass<T>(originalClass: ClassType<T>) {
const schema = schemaFromClass(originalClass);
originalClass[GeneratedSym] = schema;
const newClass = function (...args: any[]): T {
const instance = new originalClass(...args);
const originalObject = args[0];
return applySchemaForClass(originalClass, instance, originalObject);
return applySchemaForClass(schema, originalClass, instance, originalObject);
} as unknown as ClassType<T> & Schema<Partial<T>, T>;
newClass[GeneratedSym] = schema;
Object.defineProperty(newClass, 'name', {
value: originalClass.name,
});
......@@ -232,8 +237,12 @@ export function SchemaClass<T>(originalClass: ClassType<T>) {
Object.defineProperty(newClass, field, {
configurable: true,
enumerable: true,
writable: true,
value: schema[field],
get() {
return newClass[GeneratedSym][field];
},
set(value) {
newClass[GeneratedSym][field] = value;
},
});
}
for (const functionField of schemaFunctions) {
......@@ -244,10 +253,18 @@ export function SchemaClass<T>(originalClass: ClassType<T>) {
configurable: true,
enumerable: false,
writable: false,
value: Schema.prototype[functionField],
value: Schema.prototype[functionField].bind(newClass),
});
}
Object.defineProperty(newClass, 'toJSON', {
configurable: true,
enumerable: false,
writable: false,
value: () =>
Schema.prototype.toJSON.call({ ...newClass, toJSON: undefined }),
});
newClass.toString = schema.toString.bind(schema);
newClass[kSchema] = true;
return newClass;
......
......@@ -18,11 +18,23 @@ describe('Circular schema', () => {
@SchemaProperty({ type: MyProperty })
myProperty: MyProperty;
}
const schema = MyConfig as Schema<MyConfig>;
it('Should be object type', () => {
const schema = MyConfig as Schema<MyConfig>;
function checkSchema(schema: Schema) {
expect(schema.dict.myProperty.dict.foo.meta.default).toBe('bar');
expect(schema.type).toBe('object');
expect(schema.dict.myProperty.type).toBe('object');
}
it('Should be object type', () => {
checkSchema(schema);
});
it('should serialize', () => {
const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const restoredSchema = new Schema(data);
checkSchema(restoredSchema);
});
it('Should be instance', () => {
......
......@@ -41,9 +41,24 @@ class Post {
childPosts?: Post[];
}
function checkSchema(schema: Schema) {
expect(schema[kSchema]).toBeDefined();
expect(schema.dict.name.type).toBe('string');
expect(schema.dict.childPosts.inner.dict.name.type).toBe('string');
const authorSchema = schema.dict.author;
expect(authorSchema.dict.name.type).toBe('string');
}
describe('Recurse schema', () => {
it('should be a Schema', () => {
expect(Post[kSchema]).toBeDefined();
checkSchema(Post as Schema);
});
it('should serialize', () => {
const data = (Post as Schema).toJSON();
console.log(JSON.stringify(data, null, 2));
const rebuiltSchema = new Schema(data);
checkSchema(rebuiltSchema);
});
it('child should be Schema', () => {
......
......@@ -31,7 +31,9 @@ describe('Schema registration', () => {
it('should be serializable', () => {
const schema = Config as Schema<Config>;
const plainObject = new Schema(schema.toJSON());
const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const plainObject = new Schema(data);
expect(plainObject.type).toBe('object');
expect(plainObject.dict.foo.type).toBe('string');
});
......
......@@ -44,13 +44,24 @@ describe('Schema arrays', () => {
const schema = MyConfig as Schema<MyConfig>;
it('should be correct type', () => {
function checkSchema(schema: Schema) {
expect(schema.dict.foo.type).toEqual('array');
expect(schema.dict.bar.type).toEqual('array');
expect(schema.dict.myProperties.type).toEqual('array');
expect(schema.dict.notArray.type).toEqual('string');
expect(schema.dict.myTup.type).toEqual('tuple');
expect(schema.dict.myTupArr.type).toEqual('array');
}
it('should be correct type', () => {
checkSchema(schema);
});
it('should serialize', () => {
const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const restoredSchema = new Schema(data);
checkSchema(restoredSchema);
});
it('should be instance of property', () => {
......
......@@ -5,10 +5,10 @@ describe('Schema dict', () => {
@RegisterSchema()
class MyProperty {
@SchemaProperty({ default: 'default' })
name: string;
myName: string;
getName() {
return this.name;
return this.myName;
}
}
......@@ -36,11 +36,22 @@ describe('Schema dict', () => {
const schema = MyConfig as Schema<MyConfig>;
it('should be correct type', () => {
function checkSchema(schema: Schema) {
expect(schema.dict.foo.type).toEqual('dict');
expect(schema.dict.fooAndBar.type).toEqual('dict');
expect(schema.dict.myProperties.type).toEqual('dict');
expect(schema.dict.myPropertiesArr.type).toEqual('array');
}
it('should be correct type', () => {
checkSchema(schema);
});
it('should serialize', () => {
const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const restoredSchema = new Schema(data);
checkSchema(restoredSchema);
});
it('should check dict', () => {
......@@ -68,13 +79,13 @@ describe('Schema dict', () => {
const config = new MyConfig({
myProperties: {
foo: {
name: 'foo',
myName: 'foo',
},
},
myPropertiesArr: [
{
bar: {
name: 'bar',
myName: 'bar',
},
},
],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment