|  |  | 
|  | // Register a property, and interpolate its value to the halfway point. | 
|  | function registerAndInterpolateProperty(options) { | 
|  | CSS.registerProperty({ | 
|  | name: options.name, | 
|  | syntax: `${options.syntax} | none`, | 
|  | initialValue: 'none', | 
|  | inherits: false | 
|  | }); | 
|  | let animation = options.on.animate([ | 
|  | { [options.name]: options.from }, | 
|  | { [options.name]: options.to } | 
|  | ], 1000); | 
|  | animation.currentTime = 500; | 
|  | animation.pause(); | 
|  | } | 
|  |  | 
|  | // Apply a paint worklet to 'target' which verifies that the worklet-side value | 
|  | // of a set of properties is what we expect. | 
|  | // | 
|  | // The 'expected' parameter is an object where each key is the name of a | 
|  | // property to check, and each corresponding value is an array with the expected | 
|  | // (serialized) values for that property. | 
|  | function expectWorkletValues(target, expected) { | 
|  | const workletName = 'registered-property-value'; | 
|  |  | 
|  | // Wrap any single values in an array. This makes it possible to omit the | 
|  | // array if there is only one value. | 
|  | const ensureArray = x => x.constructor === Array ? x : [x]; | 
|  | expected = Object.entries(expected).map(([k, v]) => [k, ensureArray(v)]) | 
|  | .map(x => ({[x[0]]: x[1]})) | 
|  | .reduce((a, b) => Object.assign(a, b), {}); | 
|  |  | 
|  | target.style.setProperty('width', '100px'); | 
|  | target.style.setProperty('height', '100px'); | 
|  | target.style.setProperty('background-image', `paint(${workletName})`); | 
|  |  | 
|  | const worklet = ` | 
|  | const expectedData = ${JSON.stringify(expected)}; | 
|  | const expectedKeys = Object.keys(expectedData).sort(); | 
|  | registerPaint('${workletName}', class { | 
|  | static get inputProperties() { return expectedKeys; } | 
|  | paint(ctx, geom, styleMap) { | 
|  | let serialize = (v) => '[' + v.constructor.name + ' ' + v.toString() + ']'; | 
|  | let actual = expectedKeys.map(k => styleMap.getAll(k).map(serialize).join(', ')).join(' | '); | 
|  | let expected = expectedKeys.map(k => expectedData[k].join(', ')).join(' | '); | 
|  | ctx.fillStyle = (actual === expected) ? 'green' : 'red'; | 
|  | ctx.fillRect(0, 0, geom.width, geom.height); | 
|  | } | 
|  | });` | 
|  |  | 
|  | importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, worklet); | 
|  | } | 
|  |  | 
|  | // Like expectWorkletValues, but can only test a single property. | 
|  | function expectWorkletValue(target, property, expected) { | 
|  | expectWorkletValues(target, { [property]: expected }); | 
|  | } |