1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16const array1ObsObjPropsPU = tsuite("Partial update: Array of Observed Object and Properties", () => { 17 18 @Observed 19 class ClassA { 20 public c: number; 21 22 constructor(c: number) { 23 this.c = c; 24 } 25 } 26 27 class SubscribingView implements IMultiPropertiesChangeSubscriber { 28 29 private id_: number = SubscriberManager.MakeId(); 30 private label_: string; 31 32 constructor(label: string) { 33 SubscriberManager.Add(this); 34 this.label_ = label; 35 } 36 37 // globally unique id 38 id__(): number { 39 return this.id_; 40 } 41 42 // inform the subscribed property 43 // that the subscriber is about to be deleted 44 // hence , unsubscribe 45 aboutToBeDeleted(): void { 46 SubscriberManager.Delete(this.id__()); 47 } 48 49 // implements IMultiPropertiesChangePublisher 50 propertyHasChanged(info?: PropertyInfo): void { 51 console.log(`SubscribingView '${this.label_}' object property ${info ? info : 'unknown'} has changed.`); 52 } 53 } 54 55 tcase("Array of ClassA", () => { 56 let arr: ClassA[] = [new ClassA(0), new ClassA(1), new ClassA(2)]; 57 let parentView = new SubscribingView("parentView"); 58 let parentViewProp: ObservedPropertyObjectAbstractPU<ClassA[]> 59 = new ObservedPropertyObjectPU<ClassA[]>(arr, parentView, "parentViewProp"); 60 let parentViewSpy = spyOn(parentView, "propertyHasChanged"); 61 62 let childViews = [ 63 new SubscribingView("childView0"), 64 new SubscribingView("childView1"), 65 new SubscribingView("childView2") 66 ]; 67 68 let childViewProps: ObservedPropertyObjectAbstractPU<ClassA>[] = []; 69 [0, 1, 2].forEach((i) => 70 childViewProps.push( 71 new SynchedPropertyNesedObjectPU<ClassA>(arr[i], childViews[i], `${i}`)) 72 ); 73 74 75 let childViewsSpys = [ 76 spyOn(childViews[0], "propertyHasChanged"), 77 spyOn(childViews[1], "propertyHasChanged"), 78 spyOn(childViews[2], "propertyHasChanged") 79 ]; 80 81 // parentViewProp.get()[0].c = 48; 82 parentViewProp.get()[0] = new ClassA(48); 83 84 test("readback item 0", parentViewProp.get()[0].c == 48); 85 test("readback item 1", parentViewProp.get()[1].c == 1); 86 test("readback item 2", parentViewProp.get()[2].c == 2); 87 88 test("parentView: propertyHasChanged called", parentViewSpy.called); 89 90 arr.push(new ClassA(3)); 91 childViews.push(new SubscribingView("childViewAdded")); 92 childViewProps.push( 93 new SynchedPropertyNesedObjectPU<ClassA>(arr[3], childViews[3], `${3}`) 94 ); 95 96 childViewsSpys.push(spyOn(childViews[3], "propertyHasChanged")); 97 test("readback added item 3", parentViewProp.get()[3].c == 3); 98 99 arr[3].c = 17; 100 test("readback added item 3 after value change", parentViewProp.get()[3].c == 17); 101 test("childViews propertyHasChanged", childViewsSpys[3].called); 102 103 // reset spys 104 childViewsSpys[3].called = false; 105 parentViewSpy.called = false; 106 107 parentViewProp.get()[3] = new ClassA(4711); 108 test("readback added item 3 after object change", parentViewProp.get()[3].c == 4711); 109 test("parentView propertyHasChanged", parentViewSpy.called); 110 111 112 [0, 1, 2, 3].forEach(i => { 113 childViewProps[i].aboutToBeDeleted(); 114 childViews[i].aboutToBeDeleted(); 115 }); 116 parentViewProp.aboutToBeDeleted(); 117 parentView.aboutToBeDeleted(); 118 119 test(`After cleanup: SubscriberManager num of subscribers is ${SubscriberManager.NumberOfSubscribers()} should be 0 .`, 120 SubscriberManager.NumberOfSubscribers() == 0); 121 }); 122}); 123