1/* 2 * Copyright (c) 2021 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 testAppStorage = tsuite("AppStorage", () => { 17 18 tcase("size", () => { 19 AppStorage.CreateSingleton({say: "Hello", name: "Gudio"}); 20 test("AppStrorage has initial two ObservedProperties", AppStorage.Size() == 2); 21 }); 22 23 tcase("AppStorage has self set value", () => { 24 test("added 'say' is in AppStrorage", AppStorage.Has("say")); 25 }); 26 27 tcase("AppStorage remembers self set value", () => { 28 test("added 'say' wrong value", AppStorage.Get<string>("say") == "Hello"); 29 test("added 'name' wrong value", AppStorage.Get<string>("name") == "Gudio"); 30 }); 31 32 tcase("AppStorage remembers self set boolean value", () => { 33 AppStorage.SetOrCreate<boolean>("true", true); 34 test("added 'true' wrong boolean value", AppStorage.Get<boolean>("true")); 35 }); 36 37 tcase("AppStorage remembers self set number value", () => { 38 AppStorage.SetOrCreate<number>("favorite", 47); 39 40 test("added 'favorite', has correct number value", AppStorage.Get<number>("favorite") == 47); 41 test("added 'favorite' converted to string is '47'", AppStorage.Get<string>("favorite") == "47"); 42 }); 43 44 45 var link1: SubscribedAbstractProperty<string> = AppStorage.Link<string>("say"); 46 var link2: SubscribedAbstractProperty<string> = AppStorage.Link<string>("say"); 47 48 tcase("AppStorage and link1 update from link1.set", 49 () => { 50 link1.set("Anton"); 51 test("AppStorage: 'say' expected updated value is `Anton`.", AppStorage.Get<string>("say") == "Anton"); 52 test("SyncedPropertyTwoWay#1: 'say' expected updated value is `Anton`.", link2.get() == "Anton"); 53 }); 54 55 tcase("AppStorage and link2 update from link1.set", () => { 56 link1.set("Hanna"); 57 test("AppStorage: 'say' expected updated value is `Hanna`.", AppStorage.Get<string>("say") == "Hanna"); 58 test("SyncedPropertyTwoWay#2: 'say' expected updated value is `Hanna`.", link2.get() == "Hanna"); 59 }); 60 61 tcase("link1 and link2 update from AppStorage.set", () => { 62 AppStorage.Set<string>("say", "Paul"); 63 test("SyncedPropertyTwoWay#1: 'say' expected updated value is `Paul`.", link1.get() == "Paul"); 64 test("SyncedPropertyTwoWay#2: 'say' expected updated value is `Paul`.", link2.get() == "Paul"); 65 }); 66 67 AppStorage.Set("say", "Guido"); 68 let prop = AppStorage.Prop("say"); 69 70 tcase("prop.get", () => { 71 test("prop value expected `Guido`.", prop.get() == "Guido"); 72 }); 73 74 75 tcase("prop.set change value only locally.", () => { 76 prop.set("Hanna"); 77 test("prop changed value expected `Hanna`.", prop.get() == "Hanna"); 78 test("link1 unchanged value expected `Guido`.", link1.get() == "Guido"); 79 test("app unchanged value expected `Guido`.", AppStorage.Get("say") == "Guido"); 80 }) 81 82 tcase("appstorage set changes prop values", () => { 83 AppStorage.Set("say", "Anton"); 84 test("prop changed value expected `Anton`.", prop.get() == "Anton"); 85 }) 86 87 tcase("unsubscribe proptoLink1, linkToLink2", () => { 88 const asSubscribers = AppStorage.NumberOfSubscribersTo("say"); 89 link2.aboutToBeDeleted(); 90 test("link2 subscriber has been unsubscribed from as", AppStorage.NumberOfSubscribersTo("say") == asSubscribers - 1); 91 }) 92 93 class TestAClass { 94 public a: number; 95 public b: number; 96 } 97 98 let objAClass1: TestAClass = { a: 1, b: 2 }; 99 let objAClass2: TestAClass = { a: 101, b: 201 }; 100 101 tcase("ObservedObject create, get, set", () => { 102 AppStorage.SetOrCreate<TestAClass>("objAClass", objAClass1); 103 test("ObservedObject create, value read back prop 'a'", (AppStorage.Get<TestAClass>("objAClass").a == 1 && AppStorage.Get<TestAClass>("objAClass").b == 2)); 104 105 AppStorage.Get<TestAClass>("objAClass").a = 47; 106 test("ObservedObject property value change, value read back", AppStorage.Get<TestAClass>("objAClass").a == 47); 107 108 AppStorage.Set<TestAClass>("objAClass", objAClass2); 109 test("ObservedProperty of type ObservedObject set new ObservedObject, value read back", 110 AppStorage.Get<TestAClass>("objAClass").a == 101 && AppStorage.Get<TestAClass>("objAClass").b == 201); 111 112 AppStorage.Get<TestAClass>("objAClass").a = 102; 113 test("Followed by prop value change, value read back", 114 AppStorage.Get<TestAClass>("objAClass").a == 102 && AppStorage.Get<TestAClass>("objAClass").b == 201); 115 }) 116 117 let linktoObsObj = AppStorage.Link<TestAClass>("objAClass"); 118 119 tcase("ObservedObject Link create, get, set", () => { 120 121 test("link to ObservedObject, get value", linktoObsObj.get().b == 201); 122 123 linktoObsObj.get().b = 203; 124 test("link to ObservedObject, set value, read back link value", linktoObsObj.get().b == 203); 125 test("link to ObservedObject, set value, read back value from AppStorage", 126 AppStorage.Get<TestAClass>("objAClass").b == 203); 127 }) 128 129 tcase("ObservedObject Prop to Link create, get, set", () => { 130 let propToLinktoObsObj = linktoObsObj.createProp(undefined, "propToLinkObj"); 131 132 test("prop to link to ObservedObject, get value", propToLinktoObsObj.get().b == 203); 133 134 propToLinktoObsObj.get().b = 204; 135 test("prop to link to ObservedObject, set value locally, read back prop value", propToLinktoObsObj.get().b == 204); 136 test("prop to link to ObservedObject, set value locally, read back link value", linktoObsObj.get().b == 203); 137 test("prop to link to ObservedObject, set value locally, read back value from AppStorage", 138 AppStorage.Get<TestAClass>("objAClass").b == 203); 139 linktoObsObj.aboutToBeDeleted(); 140 propToLinktoObsObj.aboutToBeDeleted(); 141 }) 142 143 let proptoObsObj = AppStorage.Prop<TestAClass>("objAClass"); 144 145 tcase("ObservedObject Prop create, get, set", () => { 146 147 test("prop to ObservedObject, get value", proptoObsObj.get().b == 203); 148 149 proptoObsObj.get().b = 201; 150 test("prop to ObservedObject, set value locally, read back prop value", proptoObsObj.get().b == 201); 151 test("prop to ObservedObject, set value locally, read back original prop value from AppStorage", 152 AppStorage.Get<TestAClass>("objAClass").b == 203); 153 154 AppStorage.Set<TestAClass>("objAClass", { a: 42, b: 84 }); 155 test("prop to ObservedObject, set value to AppStorage, read back from AppStorage", 156 AppStorage.Get<TestAClass>("objAClass").b == 84); 157 test("prop to ObservedObject, set value to AppStorage, read back from prop", proptoObsObj.get().b == 84); 158 }) 159 160 tcase("ObservedObject Prop to Prop create, get, set", () => { 161 let propToPropObsObj = proptoObsObj.createProp(undefined, "propToProp"); 162 163 test("prop to prop to ObservedObject, get value", propToPropObsObj.get().a == 42); 164 165 propToPropObsObj.get().a = 201; 166 test("prop to prop to ObservedObject, set value locally, read back prop value", propToPropObsObj.get().a == 201); 167 test("prop to prop to ObservedObject, set value locally, read back value from parent prop", proptoObsObj.get().a == 42); 168 test("prop to prop to ObservedObject, set value locally, read back original prop value from AppStorage", 169 AppStorage.Get<TestAClass>("objAClass").a == 42); 170 171 AppStorage.Set<TestAClass>("objAClass", { a: 421, b: 842 }); 172 test("prop to prop to ObservedObject, set value to AppStorage, read back from AppStorage", 173 AppStorage.Get<TestAClass>("objAClass").b == 842); 174 test("prop to prop toObservedObject, set value to AppStorage, read back from prop", propToPropObsObj.get().b == 842); 175 test("prop to prop toObservedObject, set value to AppStorage, read back from parent prop", proptoObsObj.get().b == 842); 176 177 propToPropObsObj.aboutToBeDeleted(); 178 proptoObsObj.aboutToBeDeleted(); 179 }) 180 181 tcase("ObservedObject Prop create, get, set", () => { 182 183 test("prop to ObservedObject, get value", proptoObsObj.get().b == 203); 184 185 proptoObsObj.get().b = 201; 186 test("prop to ObservedObject, set value locally, read back prop value", proptoObsObj.get().b == 201); 187 test("prop to ObservedObject, set value locally, read back original prop value from AppStorage", 188 AppStorage.Get<TestAClass>("objAClass").b == 203); 189 190 AppStorage.Set<TestAClass>("objAClass", { a: 42, b: 84 }); 191 test("prop to ObservedObject, set value to AppStorage, read back from AppStorage", 192 AppStorage.Get<TestAClass>("objAClass").b == 84); 193 test("prop to ObservedObject, set value to AppStorage, read back from prop", proptoObsObj.get().b == 84); 194 }) 195 196 tcase("ObservedObject Prop to Prop create, get, set", () => { 197 let propToPropObsObj = proptoObsObj.createProp(undefined, "propToProp"); 198 199 test("prop to prop to ObservedObject, get value", propToPropObsObj.get().a == 42); 200 201 propToPropObsObj.get().a = 201; 202 test("prop to prop to ObservedObject, set value locally, read back prop value", propToPropObsObj.get().a == 201); 203 test("prop to prop to ObservedObject, set value locally, read back value from parent prop", proptoObsObj.get().a == 42); 204 test("prop to prop to ObservedObject, set value locally, read back original prop value from AppStorage", 205 AppStorage.Get<TestAClass>("objAClass").a == 42); 206 207 AppStorage.Set<TestAClass>("objAClass", { a: 421, b: 842 }); 208 test("prop to prop to ObservedObject, set value to AppStorage, read back from AppStorage", 209 AppStorage.Get<TestAClass>("objAClass").b == 842); 210 test("prop to prop toObservedObject, set value to AppStorage, read back from prop", propToPropObsObj.get().b == 842); 211 test("prop to prop toObservedObject, set value to AppStorage, read back from parent prop", proptoObsObj.get().b == 842); 212 213 propToPropObsObj.aboutToBeDeleted(); 214 proptoObsObj.aboutToBeDeleted(); 215 }) 216 217 tcase("cleanup ok", () => { 218 link1.aboutToBeDeleted(); 219 prop.aboutToBeDeleted(); 220 // note link2 and linktoLink2 have been deleted already earlier in this test suite! 221 222 const deleteOk = AppStorage.Delete("name") && AppStorage.Delete("say") && AppStorage.Delete("true") && AppStorage.Delete("favorite") && AppStorage.Delete("objAClass"); 223 test(`Deletion of props form AppStrorage without isuses`, deleteOk) 224 225 // test that manual cleanup has been complete, before calling AppStorage.NboutToBeDeleted(); 226 test(`AppStrorage has ${AppStorage.Size()} ObservedProperties: >${Array.from(AppStorage.Keys())}<, should be none.`, AppStorage.Size() == 0); 227 228 AppStorage.AboutToBeDeleted(); 229 230 test(`SubscriberManager num of subscribers is ${SubscriberManager.NumberOfSubscribers()} should be 0 .`, 231 SubscriberManager.NumberOfSubscribers() == 0); 232 233 234 }); 235 236}); 237