mirror of
https://github.com/frappe/books.git
synced 2025-02-02 12:08:27 +00:00
test: schema builder
This commit is contained in:
parent
74bfe7931c
commit
4800112ff4
63
schemas/tests/helpers.ts
Normal file
63
schemas/tests/helpers.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import Account from '../app/Account.json';
|
||||
import Customer from '../app/Customer.json';
|
||||
import JournalEntry from '../app/JournalEntry.json';
|
||||
import JournalEntryAccount from '../app/JournalEntryAccount.json';
|
||||
import Party from '../app/Party.json';
|
||||
import PartyRegional from '../regional/in/Party.json';
|
||||
import { Schema, SchemaStub, SchemaStubMap } from '../types';
|
||||
|
||||
interface AppSchemaMap extends SchemaStubMap {
|
||||
Account: SchemaStub;
|
||||
JournalEntry: SchemaStub;
|
||||
JournalEntryAccount: SchemaStub;
|
||||
Party: SchemaStub;
|
||||
Customer: SchemaStub;
|
||||
}
|
||||
|
||||
interface RegionalSchemaMap extends SchemaStubMap {
|
||||
Party: SchemaStub;
|
||||
}
|
||||
|
||||
export function getTestSchemaMap(): {
|
||||
appSchemaMap: AppSchemaMap;
|
||||
regionalSchemaMap: RegionalSchemaMap;
|
||||
} {
|
||||
const appSchemaMap = {
|
||||
Account,
|
||||
JournalEntry,
|
||||
JournalEntryAccount,
|
||||
Party,
|
||||
Customer,
|
||||
} as AppSchemaMap;
|
||||
const regionalSchemaMap = { Party: PartyRegional } as RegionalSchemaMap;
|
||||
|
||||
return {
|
||||
appSchemaMap,
|
||||
regionalSchemaMap,
|
||||
};
|
||||
}
|
||||
|
||||
export function everyFieldExists(fieldList: string[], schema: Schema): boolean {
|
||||
return fieldsExist(fieldList, schema, 'every');
|
||||
}
|
||||
|
||||
export function someFieldExists(fieldList: string[], schema: Schema): boolean {
|
||||
return fieldsExist(fieldList, schema, 'some');
|
||||
}
|
||||
|
||||
function fieldsExist(
|
||||
fieldList: string[],
|
||||
schema: Schema,
|
||||
type: 'every' | 'some'
|
||||
): boolean {
|
||||
const schemaFieldNames = schema.fields.map((f) => f.fieldname);
|
||||
return fieldList.map((f) => schemaFieldNames.includes(f))[type](Boolean);
|
||||
}
|
||||
|
||||
export function subtract(
|
||||
targetList: string[],
|
||||
...removalLists: string[][]
|
||||
): string[] {
|
||||
const removalList = removalLists.flat();
|
||||
return targetList.filter((f) => !removalList.includes(f));
|
||||
}
|
213
schemas/tests/testSchemaBuilder.spec.ts
Normal file
213
schemas/tests/testSchemaBuilder.spec.ts
Normal file
@ -0,0 +1,213 @@
|
||||
import * as assert from 'assert';
|
||||
import { cloneDeep, isEqual } from 'lodash';
|
||||
import { describe } from 'mocha';
|
||||
import { getMapFromList } from '../helpers';
|
||||
import {
|
||||
addMetaFields,
|
||||
cleanSchemas,
|
||||
getAbstractCombinedSchemas,
|
||||
getRegionalCombinedSchemas,
|
||||
} from '../index';
|
||||
import { metaSchemas } from '../schemas';
|
||||
import {
|
||||
everyFieldExists,
|
||||
getTestSchemaMap,
|
||||
someFieldExists,
|
||||
subtract,
|
||||
} from './helpers';
|
||||
|
||||
describe('Schema Builder', function () {
|
||||
const { appSchemaMap, regionalSchemaMap } = getTestSchemaMap();
|
||||
describe('Raw Schemas', function () {
|
||||
specify('Meta Properties', function () {
|
||||
assert.strictEqual(appSchemaMap.Party.isAbstract, true);
|
||||
assert.strictEqual(appSchemaMap.Customer.extends, 'Party');
|
||||
assert.strictEqual(appSchemaMap.Account.isTree, true);
|
||||
assert.strictEqual(appSchemaMap.JournalEntryAccount.isChild, true);
|
||||
});
|
||||
|
||||
specify('Field Counts', function () {
|
||||
assert.strictEqual(appSchemaMap.Account.fields?.length, 6);
|
||||
assert.strictEqual(appSchemaMap.JournalEntry.fields?.length, 8);
|
||||
assert.strictEqual(appSchemaMap.JournalEntryAccount.fields?.length, 3);
|
||||
assert.strictEqual(appSchemaMap.Party.fields?.length, 8);
|
||||
assert.strictEqual(appSchemaMap.Customer.fields?.length, undefined);
|
||||
assert.strictEqual(regionalSchemaMap.Party.fields?.length, 2);
|
||||
});
|
||||
|
||||
specify('Quick Edit Field Counts', function () {
|
||||
assert.strictEqual(appSchemaMap.Party.quickEditFields?.length, 5);
|
||||
assert.strictEqual(regionalSchemaMap.Party.quickEditFields?.length, 7);
|
||||
});
|
||||
});
|
||||
|
||||
const regionalCombined = getRegionalCombinedSchemas(
|
||||
appSchemaMap,
|
||||
regionalSchemaMap
|
||||
);
|
||||
describe('Regional Combined Schemas', function () {
|
||||
specify('Field Counts', function () {
|
||||
assert.strictEqual(regionalCombined.Party.fields?.length, 10);
|
||||
});
|
||||
|
||||
specify('Quick Edit Field Counts', function () {
|
||||
assert.strictEqual(regionalSchemaMap.Party.quickEditFields?.length, 7);
|
||||
});
|
||||
|
||||
specify('Schema Equality with App Schemas', function () {
|
||||
assert.strictEqual(
|
||||
isEqual(regionalCombined.Account, appSchemaMap.Account),
|
||||
true
|
||||
);
|
||||
assert.strictEqual(
|
||||
isEqual(regionalCombined.JournalEntry, appSchemaMap.JournalEntry),
|
||||
true
|
||||
);
|
||||
assert.strictEqual(
|
||||
isEqual(
|
||||
regionalCombined.JournalEntryAccount,
|
||||
appSchemaMap.JournalEntryAccount
|
||||
),
|
||||
true
|
||||
);
|
||||
assert.strictEqual(
|
||||
isEqual(regionalCombined.Customer, appSchemaMap.Customer),
|
||||
true
|
||||
);
|
||||
assert.strictEqual(
|
||||
isEqual(regionalCombined.Party, appSchemaMap.Party),
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const abstractCombined = cleanSchemas(
|
||||
getAbstractCombinedSchemas(regionalCombined)
|
||||
);
|
||||
describe('Abstract Combined Schemas', function () {
|
||||
specify('Meta Properties', function () {
|
||||
assert.strictEqual(abstractCombined.Customer.extends, undefined);
|
||||
});
|
||||
|
||||
specify('Abstract Schema Existance', function () {
|
||||
assert.strictEqual(abstractCombined.Party, undefined);
|
||||
});
|
||||
|
||||
specify('Field Counts', function () {
|
||||
assert.strictEqual(abstractCombined.Customer.fields?.length, 10);
|
||||
});
|
||||
|
||||
specify('Quick Edit Field Counts', function () {
|
||||
assert.strictEqual(abstractCombined.Customer.quickEditFields?.length, 7);
|
||||
});
|
||||
|
||||
specify('Schema Equality with App Schemas', function () {
|
||||
assert.strictEqual(
|
||||
isEqual(abstractCombined.Account, appSchemaMap.Account),
|
||||
true
|
||||
);
|
||||
assert.strictEqual(
|
||||
isEqual(abstractCombined.JournalEntry, appSchemaMap.JournalEntry),
|
||||
true
|
||||
);
|
||||
assert.strictEqual(
|
||||
isEqual(
|
||||
abstractCombined.JournalEntryAccount,
|
||||
appSchemaMap.JournalEntryAccount
|
||||
),
|
||||
true
|
||||
);
|
||||
assert.strictEqual(
|
||||
isEqual(abstractCombined.Customer, appSchemaMap.Customer),
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
specify('Schema Field Existance', function () {
|
||||
assert.strictEqual(
|
||||
everyFieldExists(
|
||||
regionalSchemaMap.Party.quickEditFields ?? [],
|
||||
abstractCombined.Customer
|
||||
),
|
||||
true
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const finalSchemas = addMetaFields(cloneDeep(abstractCombined));
|
||||
const metaSchemaMap = getMapFromList(metaSchemas, 'name');
|
||||
const baseFieldNames = metaSchemaMap.base.fields!.map((f) => f.fieldname);
|
||||
const childFieldNames = metaSchemaMap.child.fields!.map((f) => f.fieldname);
|
||||
const treeFieldNames = metaSchemaMap.tree.fields!.map((f) => f.fieldname);
|
||||
const submittableFieldNames = metaSchemaMap.submittable.fields!.map(
|
||||
(f) => f.fieldname
|
||||
);
|
||||
const allFieldNames = [
|
||||
...baseFieldNames,
|
||||
...childFieldNames,
|
||||
...treeFieldNames,
|
||||
...submittableFieldNames,
|
||||
];
|
||||
|
||||
describe('Final Schemas', function () {
|
||||
specify('Schema Field Existance', function () {
|
||||
assert.strictEqual(
|
||||
everyFieldExists(baseFieldNames, finalSchemas.Customer),
|
||||
true
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
someFieldExists(
|
||||
subtract(allFieldNames, baseFieldNames),
|
||||
finalSchemas.Customer
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
everyFieldExists(
|
||||
[...baseFieldNames, ...submittableFieldNames],
|
||||
finalSchemas.JournalEntry
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
someFieldExists(
|
||||
subtract(allFieldNames, baseFieldNames, submittableFieldNames),
|
||||
finalSchemas.JournalEntry
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
everyFieldExists(childFieldNames, finalSchemas.JournalEntryAccount),
|
||||
true
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
someFieldExists(
|
||||
subtract(allFieldNames, childFieldNames),
|
||||
finalSchemas.JournalEntryAccount
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
everyFieldExists(
|
||||
[...treeFieldNames, ...baseFieldNames],
|
||||
finalSchemas.Account
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
someFieldExists(
|
||||
subtract(allFieldNames, treeFieldNames, baseFieldNames),
|
||||
finalSchemas.Account
|
||||
),
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@ -107,7 +107,7 @@ export type Field =
|
||||
|
||||
export type TreeSettings = { parentField: string };
|
||||
|
||||
// prettier-ignore
|
||||
// @formattoer:off
|
||||
export interface Schema {
|
||||
name: string; // Table PK
|
||||
label: string; // Translateable UI facing name
|
||||
@ -118,7 +118,8 @@ export interface Schema {
|
||||
isSingle?: boolean; // Fields will be values in SingleValue, i.e. an Entity Attr. Value
|
||||
isAbstract?: boolean; // Not entered into db, used to extend a Subclass schema
|
||||
isSubmittable?: boolean; // For transactional types, values considered only after submit
|
||||
keywordFields?: string[]; // Used for fields that are to be used for search.
|
||||
keywordFields?: string[]; // Used to get fields that are to be used for search.
|
||||
quickEditFields?: string[]; // Used to get fields for the quickEditForm
|
||||
treeSettings?: TreeSettings; // Used to determine root nodes
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user