Browse Source

Add tests for dynamic attributes

pull/6351/head
mohamedsalem401 2 years ago
parent
commit
45ba340da0
  1. 26
      packages/core/src/data_sources/model/utils.ts
  2. 14
      packages/core/src/dom_components/model/Component.ts
  3. 1
      packages/core/src/trait_manager/model/Trait.ts
  4. 213
      packages/core/test/specs/data_sources/dynamic_values/attributes.ts

26
packages/core/src/data_sources/model/utils.ts

@ -22,3 +22,29 @@ export function isDataCondition(variable: any) {
export function evaluateVariable(variable: any, em: EditorModel) {
return isDataVariable(variable) ? new DataVariable(variable, { em }).getDataValue() : variable;
}
export function getDynamicValueInstance(valueDefinition: DynamicValueDefinition, em: EditorModel): DynamicValue {
const dynamicType = valueDefinition.type;
let dynamicVariable: DynamicValue;
switch (dynamicType) {
case DataVariableType:
dynamicVariable = new DataVariable(valueDefinition, { em: em });
break;
case ConditionalVariableType: {
const { condition, ifTrue, ifFalse } = valueDefinition;
dynamicVariable = new DataCondition(condition, ifTrue, ifFalse, { em: em });
break;
}
default:
throw new Error(`Unsupported dynamic type: ${dynamicType}`);
}
return dynamicVariable;
}
export function evaluateDynamicValueDefinition(valueDefinition: DynamicValueDefinition, em: EditorModel) {
const dynamicVariable = getDynamicValueInstance(valueDefinition, em);
return { variable: dynamicVariable, value: dynamicVariable.getDataValue() };
}

14
packages/core/src/dom_components/model/Component.ts

@ -675,16 +675,15 @@ export default class Component extends StyleableModel<ComponentProperties> {
* component.setAttributes({ id: 'test', 'data-key': 'value' });
*/
setAttributes(attrs: ObjectAny, opts: SetAttrOptions = {}) {
const attributes = this.dynamicVariableListenersOBJ.attributes;
const keys = Object.keys(attributes)
keys.forEach(attribute => {
const { propsToWatch, evaluatedProps } = evaluatePropsBeforeInstantiation(attrs, this.em);
const attrArr = Object.keys(this.dynamicVariableListenersOBJ.attributes);
attrArr.filter(attribute => attrs[attribute] !== undefined).forEach(attribute => {
this.dynamicVariableListenersOBJ.attributes[attribute].destroy();
delete this.dynamicVariableListenersOBJ.attributes[attribute];
});
this.set('attributes', { ...attrs }, opts);
const { propsToWatch } = evaluatePropsBeforeInstantiation(attrs, this.em);
this.watchAttributes(propsToWatch);
this.set('attributes', { ...evaluatedProps }, opts);
return this;
}
@ -697,9 +696,6 @@ export default class Component extends StyleableModel<ComponentProperties> {
* component.addAttributes({ 'data-key': 'value' });
*/
addAttributes(attrs: ObjectAny, opts: SetAttrOptions = {}) {
const { propsToWatch } = evaluatePropsBeforeInstantiation(attrs, this.em);
this.watchAttributes(propsToWatch);
return this.setAttributes(
{
...this.getAttributes({ noClass: true }),

1
packages/core/src/trait_manager/model/Trait.ts

@ -383,7 +383,6 @@ export default class Trait extends Model<TraitProperties> {
}
getInitValue() {
if (this.hasDynamicValue()) return this.getDynamicValue();
const { component } = this;
const name = this.getName();
let value;

213
packages/core/test/specs/data_sources/dynamic_values/attributes.ts

@ -0,0 +1,213 @@
import Editor from '../../../../src/editor/model/Editor';
import DataSourceManager from '../../../../src/data_sources';
import ComponentWrapper from '../../../../src/dom_components/model/ComponentWrapper';
import { DataVariableType } from '../../../../src/data_sources/model/DataVariable';
import { setupTestEditor } from '../../../common';
import { Component } from '../../../../src';
const staticAttributeValue = 'some tiltle';
describe('TraitDataVariable', () => {
let em: Editor;
let dsm: DataSourceManager;
let cmpRoot: ComponentWrapper;
const staticAttributes = {
staticAttribute: staticAttributeValue,
}
beforeEach(() => {
({ em, dsm, cmpRoot } = setupTestEditor());
});
afterEach(() => {
em.destroy();
});
describe('dynamic attributes', () => {
test('static and dynamic attributes', () => {
const inputDataSource = {
id: 'ds_id',
records: [{ id: 'id1', value: 'test-value' }],
};
dsm.add(inputDataSource);
const attributes = {
...staticAttributes,
dynamicAttribute: {
type: DataVariableType,
defaultValue: 'default',
path: "ds_id.id1.value",
}
}
const cmp = cmpRoot.append({
tagName: 'input',
attributes,
})[0];
testAttribute(cmp, 'dynamicAttribute', 'test-value');
testStaticAttributes(cmp);
});
test('dynamic attributes should listen to change', () => {
const dataSource = {
id: 'ds_id',
records: [{ id: 'id1', value: 'test-value' }],
};
dsm.add(dataSource);
const attributes = {
...staticAttributes,
dynamicAttribute: {
type: DataVariableType,
defaultValue: 'default',
path: "ds_id.id1.value",
}
}
const cmp = cmpRoot.append({
tagName: 'input',
attributes,
})[0];
testAttribute(cmp, 'dynamicAttribute', 'test-value');
testStaticAttributes(cmp);
changeDataSourceValue(dsm);
testAttribute(cmp, 'dynamicAttribute', 'changed-value');
});
test('dynamic attributes should listen to the latest dynamic value', () => {
const dataSource = {
id: 'ds_id',
records: [
{ id: 'id1', value: 'test-value' },
{ id: 'id2', value: 'test-value' },
],
};
dsm.add(dataSource);
const attributes = {
...staticAttributes,
dynamicAttribute: {
type: DataVariableType,
defaultValue: 'default',
path: "ds_id.id1.value",
}
}
const cmp = cmpRoot.append({
tagName: 'input',
attributes,
})[0];
cmp.addAttributes({
dynamicAttribute: {
type: DataVariableType,
defaultValue: 'default',
path: "ds_id.id2.value",
}
});
changeDataSourceValue(dsm);
testAttribute(cmp, 'dynamicAttribute', 'test-value');
});
test('dynamic attributes should stop listening to change if the value changed to static', () => {
const dataSource = {
id: 'ds_id',
records: [{ id: 'id1', value: 'test-value' }],
};
dsm.add(dataSource);
const attributes = {
...staticAttributes,
dynamicAttribute: {
type: DataVariableType,
defaultValue: 'default',
path: "ds_id.id1.value",
}
}
const cmp = cmpRoot.append({
tagName: 'input',
attributes,
})[0];
testAttribute(cmp, 'dynamicAttribute', 'test-value');
testStaticAttributes(cmp);
cmp.setAttributes({
dynamicAttribute: 'static-value'
})
changeDataSourceValue(dsm);
testAttribute(cmp, 'dynamicAttribute', 'static-value');
});
test('dynamic attributes should stop listening to change if the value changed to dynamic value', () => {
const dataSource = {
id: 'ds_id',
records: [{ id: 'id1', value: 'test-value' }],
};
dsm.add(dataSource);
const attributes = {
...staticAttributes,
dynamicAttribute: 'static-value'
}
const cmp = cmpRoot.append({
tagName: 'input',
attributes,
})[0];
cmp.setAttributes({
dynamicAttribute: {
type: DataVariableType,
defaultValue: 'default',
path: "ds_id.id1.value",
}
})
testAttribute(cmp, 'dynamicAttribute', 'test-value');
changeDataSourceValue(dsm);
testAttribute(cmp, 'dynamicAttribute', 'changed-value');
});
test('dynamic attributes should stop listening to change if the attribute was removed', () => {
const dataSource = {
id: 'ds_id',
records: [{ id: 'id1', value: 'test-value' }],
};
dsm.add(dataSource);
const attributes = {
...staticAttributes,
dynamicAttribute: {
type: DataVariableType,
defaultValue: 'default',
path: "ds_id.id1.value",
}
}
const cmp = cmpRoot.append({
tagName: 'input',
attributes,
})[0];
testAttribute(cmp, 'dynamicAttribute', 'test-value');
testStaticAttributes(cmp);
cmp.removeAttributes('dynamicAttribute');
changeDataSourceValue(dsm);
expect(cmp?.getAttributes()['dynamicAttribute']).toBe(undefined);
const input = cmp.getEl();
expect(input?.getAttribute('dynamicAttribute')).toBe(null);
});
});
});
function changeDataSourceValue(dsm: DataSourceManager) {
dsm.get('ds_id').getRecord('id1')?.set('value', 'changed-value')
}
function testStaticAttributes(cmp: Component) {
testAttribute(cmp, 'staticAttribute', staticAttributeValue)
}
function testAttribute(cmp: Component, attribute: string, value: string) {
expect(cmp?.getAttributes()[attribute]).toBe(value);
const input = cmp.getEl();
expect(input?.getAttribute(attribute)).toBe(value);
}
Loading…
Cancel
Save