1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20import chai from 'chai'; 21import sinon from 'sinon'; 22import { 23 describe, 24 before, 25 it 26} from 'mocha'; 27import { 28 fakeLog, 29 fakeLogRestore 30} from '../../fakeLog'; 31import { 32 bindSubVm, 33 bindSubVmAfterInitialized, 34 setAttr 35} from '../../../runtime/main/model/directive'; 36import { initState } from '../../../runtime/main/reactivity/state'; 37import config from '../../../runtime/main/config'; 38 39const expect = chai.expect; 40const { nativeComponentMap } = config; 41const directive = {}; 42 43function extendVm(vm, methodNames) { 44 methodNames.forEach((name) => { 45 vm[name] = directive[name]; 46 }); 47 initState(vm); 48} 49 50function initElement(el) { 51 el.setAttr = function(k, v) { 52 this.attr[k] = v; 53 }; 54 el.setStyle = function(k, v) { 55 this.style[k] = v; 56 }; 57 el.setClassStyle = function(style) { 58 this.classStyle = style; 59 }; 60 el.addEvent = function(t, h) { 61 this.event[t] = h; 62 }; 63 el.setClassList = function(classList) { 64 this.classList = classList; 65 }; 66} 67 68describe('bind external infomations to sub vm', () => { 69 fakeLog(); 70 71 let vm: any; 72 let subVm: any; 73 74 before(() => { 75 vm = { 76 data: { a: 1, b: 2, c: 'class-style1' }, 77 watchers: [], 78 app: { eventManager: { add: () => {} }}, 79 options: { 80 style: { 81 'class-style1': { 82 aaa: 1, 83 bbb: 2 84 }, 85 'class-style2': { 86 aaa: 2, 87 ccc: 3 88 } 89 } 90 }, 91 foo: function() {} 92 }; 93 extendVm(vm, []); 94 subVm = { 95 options: { 96 props: { 97 a: String, 98 b: String 99 } 100 }, 101 _props: [] 102 }; 103 }); 104 105 it('bind to no-root-element sub vm', () => { 106 bindSubVm(vm, subVm, { 107 // @ts-ignore 108 attr: { a: 3, c: 4 }, 109 110 // @ts-ignore 111 style: { a: 2 }, 112 events: { click: 'foo' } 113 }, {}); 114 expect(subVm.a).eql(3); 115 expect(subVm.b).to.be.undefined; 116 expect(subVm._rootEl).to.be.undefined; 117 }); 118 119 it('bind props with external data', () => { 120 bindSubVm(vm, subVm, { 121 // @ts-ignore 122 attr: { a: function() { 123 return this.data.b; 124 } } 125 }, {}); 126 expect(subVm.a).eql(2); 127 }); 128 129 it('bind styles to a sub vm with root element', () => { 130 subVm._rootEl = { 131 attr: {}, 132 style: {}, 133 event: [] 134 }; 135 const template: any = { 136 style: { aaa: 2, bbb: function() { 137 return this.data.a; 138 } } 139 }; 140 initElement(subVm._rootEl); 141 bindSubVm(vm, subVm, template, {}); 142 143 // @ts-ignore 144 bindSubVmAfterInitialized(vm, subVm, template, {}); 145 expect(subVm._rootEl.style.aaa).eql(2); 146 expect(subVm._rootEl.style.bbb).eql(1); 147 }); 148 149 fakeLogRestore(); 150}); 151 152/* 1531. api 7 data* ->$data set to dataset ,data ->data data set to attr; 1542. api 6 data* -> data set to dataset,data -> data set to attr(data and data* are not compatible ar compile time); 1553. api 5 data -> data set to attr. 156*/ 157describe('set $data and data to element to check API 7 scene', () => { 158 fakeLog(); 159 160 let vm: any; 161 let attr1: any; 162 let attr2: any; 163 let element: any 164 let SETTERS = { 165 attr: 'setAttr', 166 data: 'setData', 167 $data: 'setData' 168 } 169 170 before(() => { 171 vm = { 172 __data: { c: '333', d: '444'}, 173 _watchers: [], 174 }; 175 attr1 = { 176 data: '111', 177 $data: { b: '222' } 178 }; 179 attr2 = { 180 data: function () {return vm.__data.c}, 181 $data: { url: function () {return vm.__data.d} } 182 }; 183 element = { 184 dataSet: {}, 185 attr: {}, 186 watchers: [], 187 setData: function setData(key: string, value: string): void { 188 this.dataSet[key] = value; 189 }, 190 setAttr: function(key: string, value: string | number): void { 191 if (this.attr[key] === value) { 192 return; 193 } 194 this.attr[key] = value; 195 } 196 }; 197 }); 198 199 it('set data and $data to element', () => { 200 setAttr(vm, element, attr1) 201 expect(element.attr.data).eql('111'); 202 expect(element.dataSet.b).eql('222'); 203 }) 204 205 it('set data and $data which is function to element', () => { 206 setAttr(vm, element, attr2) 207 expect(element.attr.data).eql('333'); 208 expect(element.dataSet.url).eql('444'); 209 }) 210 211 fakeLogRestore(); 212}); 213 214describe('set data and data* to element to check API 6 scene', () => { 215 fakeLog(); 216 217 let vm: any; 218 let attr1: any; 219 let attr2: any; 220 let element: any 221 let SETTERS = { 222 attr: 'setAttr', 223 data: 'setData' 224 } 225 226 before(() => { 227 vm = {}; 228 attr1 = { 229 data: '111' 230 }; 231 attr2 = { 232 data: { url: '222'} 233 }; 234 element = { 235 dataSet: {}, 236 attr: {}, 237 setData: function setData(key: string, value: string): void { 238 this.dataSet[key] = value; 239 }, 240 setAttr: function(key: string, value: string | number): void { 241 if (this.attr[key] === value) { 242 return; 243 } 244 this.attr[key] = value; 245 } 246 }; 247 }); 248 249 it('set data to element', () => { 250 setAttr(vm, element, attr1) 251 expect(element.attr.data).eql('111'); 252 }) 253 254 it('set data* to element', () => { 255 setAttr(vm, element, attr2) 256 expect(element.dataSet.url).eql('222'); 257 }) 258 259 fakeLogRestore(); 260}); 261 262describe('set data only to element attr to to check API 5 scene', () => { 263 fakeLog(); 264 265 let vm: any; 266 let attr: any; 267 let element: any 268 let SETTERS = { 269 attr: 'setAttr', 270 data: 'setData' 271 } 272 273 before(() => { 274 vm = {}; 275 attr = { 276 data: '111' 277 }; 278 element = { 279 dataSet: {}, 280 attr: {}, 281 setData: function setData() {}, 282 setAttr: function(key: string, value: string | number): void { 283 if (this.attr[key] === value) { 284 return; 285 } 286 this.attr[key] = value; 287 } 288 }; 289 }); 290 291 it('set data to element', () => { 292 setAttr(vm, element, attr) 293 expect(element.attr.data).eql('111'); 294 }) 295 296 fakeLogRestore(); 297});