import { Assert, UnitTest } from '@ephox/bedrock-client'; import { Arr, Obj, Optional } from '@ephox/katamari'; import * as fc from 'fast-check'; import type { DomDefinitionDetail } from 'ephox/alloy/dom/DomDefinition'; import * as DomModification from 'ephox/alloy/dom/DomModification'; UnitTest.test('DomDefinitionTest', () => { // TODO: Add property based tests. // Since making DomDefinition just the value after defaulting, this // test became a lot less useful. Therefore, we'll just test a few // properties const arbOptionOf = (arb: fc.Arbitrary) => fc.tuple(fc.boolean(), arb).map( (arr: [boolean, string]) => arr[0] ? Optional.some(arr[1]) : Optional.none() ); const nestring = fc.string({ minLength: 1 }); const arbDefinition = fc.tuple( nestring, nestring, fc.array(nestring), fc.dictionary(nestring, nestring), fc.dictionary(nestring, nestring), arbOptionOf(fc.string()), arbOptionOf(fc.string()) ).map((arr: [string, string, string[], Record, Record, Optional, Optional]): DomDefinitionDetail => ({ uid: arr[0], tag: arr[1], classes: arr[2], attributes: arr[3], styles: arr[4], value: arr[5], innerHtml: arr[6], domChildren: [ ] })); const arbModification = fc.tuple( fc.array(nestring), fc.dictionary(nestring, nestring), fc.dictionary(nestring, nestring) ).map((arr: [ string[], Record, Record]): DomModification.DomModification => ({ classes: arr[0], attributes: arr[1], styles: arr[2] })); fc.assert(fc.property(arbDefinition, arbModification, (defn, mod) => { const result = DomModification.merge(defn, mod); Assert.eq( () => 'All classes in mod should be in final result: ' + JSON.stringify(result, null, 2) + '. Should be none left over.', [ ], Arr.difference(mod.classes, result.classes) ); Assert.eq( () => 'All classes in defn should be in final result ' + JSON.stringify(result, null, 2) + '.too. Should be none left over.', [ ], Arr.difference(defn.classes, result.classes) ); Assert.eq( () => 'All styles from modification should be in final result' + JSON.stringify(result, null, 2) + '.', true, Obj.find(mod.styles, (v, k) => result.styles[k] !== v).isNone() ); Obj.each(defn.styles, (v, k) => { Assert.eq( () => 'Defn Style: ' + k + '=' + v + ' should appear in result: ' + JSON.stringify(result, null, 2) + '., unless modification changed it', true, result.styles[k] === v || result.styles[k] === mod.styles[k] && Obj.has(mod.styles, k) ); }); Assert.eq( () => 'All attributes from modification should be in final result' + JSON.stringify(result, null, 2) + '.', true, Obj.find(mod.attributes, (v, k) => result.attributes[k] !== v).isNone() ); Obj.each(defn.attributes, (v, k) => { Assert.eq( () => 'Defn attribute: ' + k + '=' + v + ' should appear in result: ' + JSON.stringify(result, null, 2) + '., unless modification changed it', true, result.attributes[k] === v || result.attributes[k] === mod.attributes[k] && Obj.has(mod.attributes, k) ); }); })); });