UNPKG

jinaga

Version:

Data management for web and mobile applications.

157 lines (133 loc) 5.77 kB
import { computeHash, verifyHash } from '../../src/fact/hash'; import { dehydrateFact, Hydration } from '../../src/fact/hydrate'; import { JinagaTest } from '../../src/jinaga-test'; describe ('Hash', () => { it('should be independent of field order', () => { const hash1 = computeHash({ a: 'one', b: 'two' }, {}); const hash2 = computeHash({ b: 'two', a: 'one' }, {}); expect(hash1).toEqual(hash2); }); it('should be independent of array order', () => { const one = { type: 'pred', hash: 'one' }; const two = { type: 'pred', hash: 'two' }; const hash1 = computeHash({}, { preds: [ one, two ] }); const hash2 = computeHash({}, { preds: [ two, one ] }); expect(hash1).toEqual(hash2); }); it('should verify hash', () => { const records = dehydrateFact({ type: 'Child', parent: { type: 'Parent', identifier: 'fee' }, value: 'fum' }); expect(verifyHash(records[0])).toBeTruthy(); expect(verifyHash(records[1])).toBeTruthy(); }) }); describe('Nullable Predecessors', () => { it('should create fact with null predecessor and omit it from canonical form', () => { // Given a fact with a null predecessor const factWithNullPredecessor = { type: 'ChildWithOptionalParent', parent: null, name: 'orphan' }; // When dehydrating the fact const records = dehydrateFact(factWithNullPredecessor); // Then no exception should be thrown during creation expect(records).toBeDefined(); expect(records.length).toBe(1); // And the canonical form should omit the null predecessor const record = records[0]; expect(record.predecessors).toEqual({}); expect(record.fields).toEqual({ name: 'orphan' }); expect(record.type).toBe('ChildWithOptionalParent'); // And deserialization should result in the property being undefined const hydration = new Hydration(records); const hydratedFact = hydration.hydrate({ type: record.type, hash: record.hash }); expect(hydratedFact.parent).toBeUndefined(); expect(hydratedFact.name).toBe('orphan'); expect(hydratedFact.type).toBe('ChildWithOptionalParent'); }); it('should create fact with undefined predecessor and omit it from canonical form', () => { // Given a fact with an undefined predecessor const factWithUndefinedPredecessor = { type: 'ChildWithOptionalParent', parent: undefined, name: 'orphan' }; // When dehydrating the fact const records = dehydrateFact(factWithUndefinedPredecessor); // Then no exception should be thrown during creation expect(records).toBeDefined(); expect(records.length).toBe(1); // And the canonical form should omit the undefined predecessor const record = records[0]; expect(record.predecessors).toEqual({}); expect(record.fields).toEqual({ name: 'orphan' }); expect(record.type).toBe('ChildWithOptionalParent'); // And deserialization should result in the property being undefined const hydration = new Hydration(records); const hydratedFact = hydration.hydrate({ type: record.type, hash: record.hash }); expect(hydratedFact.parent).toBeUndefined(); expect(hydratedFact.name).toBe('orphan'); expect(hydratedFact.type).toBe('ChildWithOptionalParent'); }); }); describe('Fact Validation', () => { it('should omit predecessor when fact contains null predecessor', async () => { // Given a Jinaga instance const j = JinagaTest.create({}); // When attempting to create a fact with a null predecessor const factWithNullPredecessor = { type: 'ChildWithNullParent', parent: null, name: 'non-parented child' }; // Then the fact should be created, and the null predecessor should be omitted const createdFact = await j.fact(factWithNullPredecessor); expect(createdFact).toBeDefined(); expect(createdFact.type).toBe('ChildWithNullParent'); expect(createdFact.parent).toBeUndefined(); expect(createdFact.name).toBe('non-parented child'); }); }); describe("Fact with null predecessor", () => { it("should create a fact and omit null predecessors in canonical form and deserialization", async () => { // Given a Jinaga instance const j = JinagaTest.create({}); const parent = await j.fact({ type: "Parent", name: "Parent Fact" }); // When attempting to create a fact with an array of predecessors that includes null const factWithNullPredecessor = { type: "ChildWithMultipleParents", parents: [parent, null], name: "missing-parent child" }; // Then the fact should be created without throwing an error const createdFact = await j.fact(factWithNullPredecessor); expect(createdFact).toBeDefined(); expect(createdFact.type).toBe("ChildWithMultipleParents"); expect(createdFact.parents).toBeDefined(); expect(createdFact.parents.length).toBe(1); // Only the valid parent should be included }); });