/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import chai from 'chai'; import sinon from 'sinon'; import { describe, before, it } from 'mocha'; import { fakeLog, fakeLogRestore } from '../../fakeLog'; import { bindSubVm, bindSubVmAfterInitialized, setAttr } from '../../../runtime/main/model/directive'; import { initState } from '../../../runtime/main/reactivity/state'; import config from '../../../runtime/main/config'; const expect = chai.expect; const { nativeComponentMap } = config; const directive = {}; function extendVm(vm, methodNames) { methodNames.forEach((name) => { vm[name] = directive[name]; }); initState(vm); } function initElement(el) { el.setAttr = function(k, v) { this.attr[k] = v; }; el.setStyle = function(k, v) { this.style[k] = v; }; el.setClassStyle = function(style) { this.classStyle = style; }; el.addEvent = function(t, h) { this.event[t] = h; }; el.setClassList = function(classList) { this.classList = classList; }; } describe('bind external infomations to sub vm', () => { fakeLog(); let vm: any; let subVm: any; before(() => { vm = { data: { a: 1, b: 2, c: 'class-style1' }, watchers: [], app: { eventManager: { add: () => {} }}, options: { style: { 'class-style1': { aaa: 1, bbb: 2 }, 'class-style2': { aaa: 2, ccc: 3 } } }, foo: function() {} }; extendVm(vm, []); subVm = { options: { props: { a: String, b: String } }, _props: [] }; }); it('bind to no-root-element sub vm', () => { bindSubVm(vm, subVm, { // @ts-ignore attr: { a: 3, c: 4 }, // @ts-ignore style: { a: 2 }, events: { click: 'foo' } }, {}); expect(subVm.a).eql(3); expect(subVm.b).to.be.undefined; expect(subVm._rootEl).to.be.undefined; }); it('bind props with external data', () => { bindSubVm(vm, subVm, { // @ts-ignore attr: { a: function() { return this.data.b; } } }, {}); expect(subVm.a).eql(2); }); it('bind styles to a sub vm with root element', () => { subVm._rootEl = { attr: {}, style: {}, event: [] }; const template: any = { style: { aaa: 2, bbb: function() { return this.data.a; } } }; initElement(subVm._rootEl); bindSubVm(vm, subVm, template, {}); // @ts-ignore bindSubVmAfterInitialized(vm, subVm, template, {}); expect(subVm._rootEl.style.aaa).eql(2); expect(subVm._rootEl.style.bbb).eql(1); }); fakeLogRestore(); }); /* 1. api 7 data* ->$data set to dataset ,data ->data data set to attr; 2. api 6 data* -> data set to dataset,data -> data set to attr(data and data* are not compatible ar compile time); 3. api 5 data -> data set to attr. */ describe('set $data and data to element to check API 7 scene', () => { fakeLog(); let vm: any; let attr1: any; let attr2: any; let element: any let SETTERS = { attr: 'setAttr', data: 'setData', $data: 'setData' } before(() => { vm = { __data: { c: '333', d: '444'}, _watchers: [], }; attr1 = { data: '111', $data: { b: '222' } }; attr2 = { data: function () {return vm.__data.c}, $data: { url: function () {return vm.__data.d} } }; element = { dataSet: {}, attr: {}, watchers: [], setData: function setData(key: string, value: string): void { this.dataSet[key] = value; }, setAttr: function(key: string, value: string | number): void { if (this.attr[key] === value) { return; } this.attr[key] = value; } }; }); it('set data and $data to element', () => { setAttr(vm, element, attr1) expect(element.attr.data).eql('111'); expect(element.dataSet.b).eql('222'); }) it('set data and $data which is function to element', () => { setAttr(vm, element, attr2) expect(element.attr.data).eql('333'); expect(element.dataSet.url).eql('444'); }) fakeLogRestore(); }); describe('set data and data* to element to check API 6 scene', () => { fakeLog(); let vm: any; let attr1: any; let attr2: any; let element: any let SETTERS = { attr: 'setAttr', data: 'setData' } before(() => { vm = {}; attr1 = { data: '111' }; attr2 = { data: { url: '222'} }; element = { dataSet: {}, attr: {}, setData: function setData(key: string, value: string): void { this.dataSet[key] = value; }, setAttr: function(key: string, value: string | number): void { if (this.attr[key] === value) { return; } this.attr[key] = value; } }; }); it('set data to element', () => { setAttr(vm, element, attr1) expect(element.attr.data).eql('111'); }) it('set data* to element', () => { setAttr(vm, element, attr2) expect(element.dataSet.url).eql('222'); }) fakeLogRestore(); }); describe('set data only to element attr to to check API 5 scene', () => { fakeLog(); let vm: any; let attr: any; let element: any let SETTERS = { attr: 'setAttr', data: 'setData' } before(() => { vm = {}; attr = { data: '111' }; element = { dataSet: {}, attr: {}, setData: function setData() {}, setAttr: function(key: string, value: string | number): void { if (this.attr[key] === value) { return; } this.attr[key] = value; } }; }); it('set data to element', () => { setAttr(vm, element, attr) expect(element.attr.data).eql('111'); }) fakeLogRestore(); });