1 /* 2 * Copyright (c) 2025 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 16 #include <gtest/gtest.h> 17 #include <json/json.h> 18 #include <json/value.h> 19 20 #include "symbol_resource/symbol_config_parser.h" 21 22 using namespace testing; 23 using namespace testing::ext; 24 25 namespace { 26 const char* ROOT_LAYERS_JSON_STR = R"({ 27 "symbol_layers_grouping": [ 28 { 29 "native_glyph_id": 1001, 30 "symbol_glyph_id": 2001, 31 "layers": [ 32 { "components": [1, 2, 3] }, 33 { "components": [4, 5] } 34 ], 35 "render_modes": [ 36 { 37 "mode": "monochrome", 38 "render_groups": [ 39 { 40 "group_indexes": [ { "layer_indexes": [0] } ], 41 "default_color": "#FF00FF", 42 "fix_alpha": 0.5 43 } 44 ] 45 } 46 ], 47 "animation_settings": [ 48 { 49 "animation_types": ["scale"], 50 "group_settings": [ 51 { 52 "group_indexes": [ { "layer_indexes": [0] } ], 53 "animation_index": 2 54 } 55 ] 56 }, 57 { 58 "animation_types": ["disable"], 59 "common_sub_type": "up", 60 "slope": -1.0000001192092896, 61 "group_settings": [{ 62 "animation_index": -1, 63 "group_indexes": [{ 64 "layer_indexes": [0] 65 }] 66 }, { 67 "animation_index": 0, 68 "group_indexes": [{ 69 "mask_indexes": [1] 70 }] 71 }, { 72 "animation_index": 0, 73 "group_indexes": [{ 74 "layer_indexes": [2] 75 }] 76 }] 77 } 78 ] 79 } 80 ] 81 })"; 82 83 const char* ROOT_ANIMATIONS_JSON_STR = R"({ 84 "animations": [ 85 { 86 "animation_type": "scale", 87 "animation_parameters": [ 88 { 89 "animation_mode": 1, 90 "common_sub_type": "up", 91 "group_parameters": [ 92 [ 93 { "curve": "spring", "duration": 200 } 94 ] 95 ] 96 } 97 ] 98 }, 99 { 100 "animation_type": "disable", 101 "animation_parameters": [ 102 { 103 "animation_mode": 0, 104 "common_sub_type": "up", 105 "group_parameters": [ 106 [ 107 { 108 "curve": "friction", 109 "curve_args": { 110 "ctrlX1": 0.2, 111 "ctrlY1": 0, 112 "ctrlX2": 0.2, 113 "ctrlY2": 1 114 }, 115 "duration": 200, 116 "delay": 0, 117 "properties": { 118 "sx": [ 119 1, 120 0.9 121 ], 122 "sy": [ 123 1, 124 0.9 125 ] 126 } 127 }, 128 { 129 "curve": "friction", 130 "curve_args": { 131 "ctrlX1": 0.2, 132 "ctrlY1": 0, 133 "ctrlX2": 0.2, 134 "ctrlY2": 1 135 }, 136 "duration": 150, 137 "delay": 200, 138 "properties": { 139 "sx": [ 140 0.9, 141 1.07 142 ], 143 "sy": [ 144 0.9, 145 1.07 146 ] 147 } 148 } 149 ] 150 ] 151 }, 152 { 153 "animation_mode": 0, 154 "common_sub_type": "down", 155 "group_parameters": [] 156 } 157 ] 158 } 159 ] 160 })"; 161 162 const char* ROOT_INVALID_JSON_STR = R"({ 163 "test": [], 164 "common_animations": {}, 165 "special_animations": {}, 166 "symbol_layers_grouping": {} 167 })"; 168 } 169 170 class SymbolConfigParserTest : public testing::Test { 171 public: SetUp()172 void SetUp() override 173 { 174 BuildValidLayersGroupingJson(); 175 BuildValidAnimationsJson(); 176 BuildInvalidJson(); 177 } 178 179 Json::Value rootLayers_; 180 Json::Value rootAnimations_; 181 Json::Value rootInvalid_; 182 183 private: BuildValidLayersGroupingJson()184 void BuildValidLayersGroupingJson() 185 { 186 Json::Reader reader; 187 EXPECT_TRUE(reader.parse(ROOT_LAYERS_JSON_STR, rootLayers_)); 188 } 189 BuildValidAnimationsJson()190 void BuildValidAnimationsJson() 191 { 192 Json::Reader reader; 193 EXPECT_TRUE(reader.parse(ROOT_ANIMATIONS_JSON_STR, rootAnimations_)); 194 } 195 BuildInvalidJson()196 void BuildInvalidJson() 197 { 198 Json::Reader reader; 199 EXPECT_TRUE(reader.parse(ROOT_INVALID_JSON_STR, rootInvalid_)); 200 } 201 }; 202 203 /* 204 * @tc.name: SymbolConfigParserTest001 205 * @tc.desc: test for lack native_glyph_id 206 * @tc.type: FUNC 207 */ 208 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest001, TestSize.Level0) 209 { 210 rootLayers_["symbol_layers_grouping"][0].removeMember("native_glyph_id"); 211 std::unordered_map<uint16_t, RSSymbolLayersGroups> symbolConfig; 212 EXPECT_TRUE(OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolLayersGrouping( 213 rootLayers_["symbol_layers_grouping"], symbolConfig)); 214 EXPECT_TRUE(symbolConfig.empty()); 215 } 216 217 /* 218 * @tc.name: SymbolConfigParserTest002 219 * @tc.desc: test for error native_glyph_id 220 * @tc.type: FUNC 221 */ 222 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest002, TestSize.Level0) 223 { 224 rootLayers_["symbol_layers_grouping"][0]["native_glyph_id"] = "invalid_id"; 225 std::unordered_map<uint16_t, RSSymbolLayersGroups> symbolConfig; 226 EXPECT_TRUE(OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolLayersGrouping( 227 rootLayers_["symbol_layers_grouping"], symbolConfig)); 228 EXPECT_TRUE(symbolConfig.empty()); 229 } 230 231 /* 232 * @tc.name: SymbolConfigParserTest003 233 * @tc.desc: test for invalid color 234 * @tc.type: FUNC 235 */ 236 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest003, TestSize.Level0) 237 { 238 rootLayers_["symbol_layers_grouping"][0]["render_modes"][0]["render_groups"][0]["default_color"] = "INVALID_COLOR"; 239 std::unordered_map<uint16_t, RSSymbolLayersGroups> symbolConfig; 240 EXPECT_TRUE(OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolLayersGrouping( 241 rootLayers_["symbol_layers_grouping"], symbolConfig)); 242 auto& renderGroups = symbolConfig.at(1001).renderModeGroups.begin()->second; 243 // default value is 0 244 EXPECT_EQ(renderGroups[0].color.r, 0); 245 } 246 247 /* 248 * @tc.name: SymbolConfigParserTest004 249 * @tc.desc: test for lack animation_type 250 * @tc.type: FUNC 251 */ 252 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest004, TestSize.Level0) 253 { 254 rootAnimations_["animations"][0].removeMember("animation_type"); 255 rootAnimations_["animations"][1].removeMember("animation_type"); 256 std::unordered_map<RSAnimationType, RSAnimationInfo> animationInfos; 257 OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolAnimations(rootAnimations_["animations"], animationInfos); 258 EXPECT_TRUE(animationInfos.empty()); 259 } 260 261 /* 262 * @tc.name: SymbolConfigParserTest005 263 * @tc.desc: test for invalid common_sub_type 264 * @tc.type: FUNC 265 */ 266 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest005, TestSize.Level0) 267 { 268 rootAnimations_["animations"][0]["animation_parameters"][0]["common_sub_type"] = "invalid_direction"; 269 std::unordered_map<RSAnimationType, RSAnimationInfo> animationInfos; 270 OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolAnimations(rootAnimations_["animations"], animationInfos); 271 auto& animInfo = animationInfos.at(RSAnimationType::SCALE_TYPE); 272 EXPECT_EQ(animInfo.animationParas.begin()->second.commonSubType, RSCommonSubType::DOWN); 273 } 274 275 /* 276 * @tc.name: SymbolConfigParserTest006 277 * @tc.desc: test for empty layers 278 * @tc.type: FUNC 279 */ 280 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest006, TestSize.Level0) 281 { 282 rootLayers_["symbol_layers_grouping"][0]["layers"] = Json::arrayValue; 283 std::unordered_map<uint16_t, RSSymbolLayersGroups> symbolConfig; 284 EXPECT_TRUE(OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolLayersGrouping( 285 rootLayers_["symbol_layers_grouping"], symbolConfig)); 286 EXPECT_TRUE(symbolConfig.at(1001).layers.empty()); 287 } 288 289 /* 290 * @tc.name: SymbolConfigParserTest007 291 * @tc.desc: test for valid symbol layers data 292 * @tc.type: FUNC 293 */ 294 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest007, TestSize.Level0) 295 { 296 std::unordered_map<uint16_t, RSSymbolLayersGroups> symbolConfig; 297 EXPECT_TRUE(OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolLayersGrouping( 298 rootLayers_["symbol_layers_grouping"], symbolConfig)); 299 auto& group = symbolConfig.at(1001); 300 EXPECT_EQ(group.symbolGlyphId, 2001); 301 EXPECT_EQ(group.layers.size(), 2); 302 EXPECT_EQ(group.layers[0], std::vector<size_t>({1, 2, 3})); 303 EXPECT_EQ(group.animationSettings.size(), 2); 304 EXPECT_EQ(group.animationSettings[0].animationTypes[0], RSAnimationType::SCALE_TYPE); 305 } 306 307 /* 308 * @tc.name: SymbolConfigParserTest008 309 * @tc.desc: test for valid symbol animations data 310 * @tc.type: FUNC 311 */ 312 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest008, TestSize.Level0) 313 { 314 std::unordered_map<RSAnimationType, RSAnimationInfo> animationInfos; 315 OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolAnimations(rootAnimations_["animations"], animationInfos); 316 EXPECT_FALSE(animationInfos.empty()); 317 auto& animPara = animationInfos.at(RSAnimationType::SCALE_TYPE).animationParas.begin()->second; 318 EXPECT_EQ(animPara.animationMode, 1); 319 EXPECT_EQ(animPara.commonSubType, RSCommonSubType::UP); 320 } 321 322 /* 323 * @tc.name: SymbolConfigParserTest009 324 * @tc.desc: test for not array layers 325 * @tc.type: FUNC 326 */ 327 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest009, TestSize.Level0) 328 { 329 rootLayers_["symbol_layers_grouping"] = Json::objectValue; 330 std::unordered_map<uint16_t, RSSymbolLayersGroups> symbolConfig; 331 EXPECT_FALSE(OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolLayersGrouping( 332 rootLayers_["symbol_layers_grouping"], symbolConfig)); 333 } 334 335 /* 336 * @tc.name: SymbolConfigParserTest010 337 * @tc.desc: test for not array animation 338 * @tc.type: FUNC 339 */ 340 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest010, TestSize.Level0) 341 { 342 rootAnimations_["animations"] = Json::objectValue; 343 std::unordered_map<RSAnimationType, RSAnimationInfo> animationInfos; 344 EXPECT_FALSE( 345 OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolAnimations(rootAnimations_["animations"], animationInfos)); 346 } 347 348 /* 349 * @tc.name: SymbolConfigParserTest011 350 * @tc.desc: test for invalid json 351 * @tc.type: FUNC 352 */ 353 HWTEST_F(SymbolConfigParserTest, SymbolConfigParserTest011, TestSize.Level0) 354 { 355 std::unordered_map<RSAnimationType, RSAnimationInfo> animationInfos; 356 std::unordered_map<uint16_t, RSSymbolLayersGroups> symbolConfig; 357 EXPECT_TRUE(OHOS::Rosen::Symbol::SymbolConfigParser::ParseSymbolConfig(rootInvalid_, symbolConfig, animationInfos)); 358 } 359