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