@openui5/sap.ui.core 1.119.1 → 1.120.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (968) hide show
  1. package/THIRDPARTY.txt +6 -6
  2. package/package.json +1 -1
  3. package/src/jquery.sap.global.js +40 -111
  4. package/src/jquery.sap.properties.js +7 -1
  5. package/src/jquery.sap.resources.js +1 -1
  6. package/src/jquery.sap.script.js +5 -3
  7. package/src/jquery.sap.storage.js +6 -3
  8. package/src/sap/base/Event.js +32 -78
  9. package/src/sap/base/Eventing.js +114 -271
  10. package/src/sap/base/Log.js +21 -1
  11. package/src/sap/base/config.js +14 -9
  12. package/src/sap/base/i18n/Formatting.js +400 -256
  13. package/src/sap/base/i18n/LanguageTag.js +64 -66
  14. package/src/sap/base/i18n/Localization.js +125 -87
  15. package/src/sap/base/i18n/ResourceBundle.js +1 -1
  16. package/src/sap/base/i18n/date/CalendarType.js +2 -2
  17. package/src/sap/base/i18n/date/CalendarWeekNumbering.js +2 -2
  18. package/src/sap/base/i18n/date/TimezoneUtils.js +43 -6
  19. package/src/sap/base/util/LoaderExtensions.js +8 -2
  20. package/src/sap/base/util/mixedFetch.js +1 -0
  21. package/src/sap/base/util/resolveReference.js +31 -13
  22. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  23. package/src/sap/base/util/restricted/_castArray.js +1 -1
  24. package/src/sap/base/util/restricted/_compact.js +1 -1
  25. package/src/sap/base/util/restricted/_curry.js +1 -1
  26. package/src/sap/base/util/restricted/_debounce.js +1 -1
  27. package/src/sap/base/util/restricted/_difference.js +1 -1
  28. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  29. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  30. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  31. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  32. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  33. package/src/sap/base/util/restricted/_flatten.js +1 -1
  34. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  35. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  36. package/src/sap/base/util/restricted/_intersection.js +1 -1
  37. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  38. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  39. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  40. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  41. package/src/sap/base/util/restricted/_isNil.js +1 -1
  42. package/src/sap/base/util/restricted/_max.js +1 -1
  43. package/src/sap/base/util/restricted/_merge.js +1 -1
  44. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  45. package/src/sap/base/util/restricted/_min.js +1 -1
  46. package/src/sap/base/util/restricted/_omit.js +1 -1
  47. package/src/sap/base/util/restricted/_pick.js +1 -1
  48. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  49. package/src/sap/base/util/restricted/_throttle.js +1 -1
  50. package/src/sap/base/util/restricted/_toArray.js +1 -1
  51. package/src/sap/base/util/restricted/_union.js +1 -1
  52. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  53. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  54. package/src/sap/base/util/restricted/_uniq.js +1 -1
  55. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  56. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  57. package/src/sap/base/util/restricted/_without.js +1 -1
  58. package/src/sap/base/util/restricted/_xor.js +1 -1
  59. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  60. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  61. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  62. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  63. package/src/sap/base/util/syncFetch.js +1 -0
  64. package/src/sap/ui/Device.js +3 -3
  65. package/src/sap/ui/Global.js +6 -7
  66. package/src/sap/ui/base/BindingInfo.js +3 -3
  67. package/src/sap/ui/base/BindingParser.js +5 -2
  68. package/src/sap/ui/base/DataType.js +57 -1
  69. package/src/sap/ui/base/DesignTime.js +69 -0
  70. package/src/sap/ui/base/Event.js +2 -2
  71. package/src/sap/ui/base/EventProvider.js +1 -1
  72. package/src/sap/ui/base/ExpressionParser.js +25 -4
  73. package/src/sap/ui/base/Interface.js +1 -1
  74. package/src/sap/ui/base/ManagedObject.js +102 -85
  75. package/src/sap/ui/base/ManagedObjectMetadata.js +53 -31
  76. package/src/sap/ui/base/ManagedObjectObserver.js +1 -0
  77. package/src/sap/ui/base/Metadata.js +3 -3
  78. package/src/sap/ui/base/Object.js +19 -1
  79. package/src/sap/ui/base/ObjectPool.js +1 -1
  80. package/src/sap/ui/core/.library +3 -3
  81. package/src/sap/ui/core/AnimationMode.js +2 -2
  82. package/src/sap/ui/core/AppCacheBuster.js +30 -18
  83. package/src/sap/ui/core/BusyIndicator.js +1 -1
  84. package/src/sap/ui/core/CalendarType.js +6 -0
  85. package/src/sap/ui/core/Component.js +175 -86
  86. package/src/sap/ui/core/ComponentContainer.js +6 -5
  87. package/src/sap/ui/core/ComponentMetadata.js +3 -4
  88. package/src/sap/ui/core/ComponentSupport.js +1 -1
  89. package/src/sap/ui/core/Configuration.js +395 -709
  90. package/src/sap/ui/core/Control.js +1 -1
  91. package/src/sap/ui/core/ControlBehavior.js +37 -28
  92. package/src/sap/ui/core/Core.js +338 -216
  93. package/src/sap/ui/core/CustomData.js +1 -1
  94. package/src/sap/ui/core/DeclarativeSupport.js +3 -1
  95. package/src/sap/ui/core/Element.js +24 -10
  96. package/src/sap/ui/core/ElementMetadata.js +1 -1
  97. package/src/sap/ui/core/EnabledPropagator.js +3 -2
  98. package/src/sap/ui/core/EventBus.js +1 -1
  99. package/src/sap/ui/core/Fragment.js +3 -3
  100. package/src/sap/ui/core/HTML.js +1 -1
  101. package/src/sap/ui/core/History.js +1 -1
  102. package/src/sap/ui/core/Icon.js +1 -1
  103. package/src/sap/ui/core/IndicationColorSupport.js +13 -1
  104. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  105. package/src/sap/ui/core/InvisibleMessage.js +2 -3
  106. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  107. package/src/sap/ui/core/InvisibleText.js +17 -1
  108. package/src/sap/ui/core/Item.js +1 -1
  109. package/src/sap/ui/core/LabelEnablement.js +8 -1
  110. package/src/sap/ui/core/LayoutData.js +1 -1
  111. package/src/sap/ui/core/Lib.js +253 -57
  112. package/src/sap/ui/core/ListItem.js +1 -1
  113. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  114. package/src/sap/ui/core/Locale.js +1 -1
  115. package/src/sap/ui/core/LocaleData.js +118 -32
  116. package/src/sap/ui/core/Manifest.js +4 -2
  117. package/src/sap/ui/core/Message.js +1 -1
  118. package/src/sap/ui/core/Placeholder.js +18 -0
  119. package/src/sap/ui/core/Popup.js +5 -0
  120. package/src/sap/ui/core/RenderManager.js +21 -17
  121. package/src/sap/ui/core/Renderer.js +1 -1
  122. package/src/sap/ui/core/Rendering.js +51 -47
  123. package/src/sap/ui/core/ResizeHandler.js +2 -2
  124. package/src/sap/ui/core/ScrollBar.js +1 -1
  125. package/src/sap/ui/core/SeparatorItem.js +1 -1
  126. package/src/sap/ui/core/Shortcut.js +5 -3
  127. package/src/sap/ui/core/Supportability.js +146 -0
  128. package/src/sap/ui/core/Theming.js +130 -88
  129. package/src/sap/ui/core/Title.js +1 -1
  130. package/src/sap/ui/core/TooltipBase.js +4 -3
  131. package/src/sap/ui/core/UIArea.js +5 -4
  132. package/src/sap/ui/core/UIComponent.js +38 -12
  133. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  134. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  135. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  136. package/src/sap/ui/core/XMLComposite.js +1 -1
  137. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  138. package/src/sap/ui/core/XMLTemplateProcessor.js +3 -3
  139. package/src/sap/ui/core/_IconRegistry.js +13 -6
  140. package/src/sap/ui/core/cldr/ar.json +143 -137
  141. package/src/sap/ui/core/cldr/ar_EG.json +143 -137
  142. package/src/sap/ui/core/cldr/ar_SA.json +143 -137
  143. package/src/sap/ui/core/cldr/bg.json +423 -423
  144. package/src/sap/ui/core/cldr/ca.json +541 -494
  145. package/src/sap/ui/core/cldr/cs.json +475 -364
  146. package/src/sap/ui/core/cldr/cy.json +656 -477
  147. package/src/sap/ui/core/cldr/da.json +334 -275
  148. package/src/sap/ui/core/cldr/de.json +388 -291
  149. package/src/sap/ui/core/cldr/de_AT.json +388 -291
  150. package/src/sap/ui/core/cldr/de_CH.json +394 -297
  151. package/src/sap/ui/core/cldr/el.json +169 -166
  152. package/src/sap/ui/core/cldr/el_CY.json +169 -166
  153. package/src/sap/ui/core/cldr/en.json +558 -521
  154. package/src/sap/ui/core/cldr/en_AU.json +558 -520
  155. package/src/sap/ui/core/cldr/en_GB.json +476 -439
  156. package/src/sap/ui/core/cldr/en_HK.json +520 -482
  157. package/src/sap/ui/core/cldr/en_IE.json +486 -448
  158. package/src/sap/ui/core/cldr/en_IN.json +466 -428
  159. package/src/sap/ui/core/cldr/en_NZ.json +506 -468
  160. package/src/sap/ui/core/cldr/en_PG.json +506 -468
  161. package/src/sap/ui/core/cldr/en_SG.json +506 -468
  162. package/src/sap/ui/core/cldr/en_ZA.json +486 -448
  163. package/src/sap/ui/core/cldr/es.json +473 -468
  164. package/src/sap/ui/core/cldr/es_AR.json +445 -440
  165. package/src/sap/ui/core/cldr/es_BO.json +479 -474
  166. package/src/sap/ui/core/cldr/es_CL.json +469 -464
  167. package/src/sap/ui/core/cldr/es_CO.json +387 -381
  168. package/src/sap/ui/core/cldr/es_MX.json +502 -497
  169. package/src/sap/ui/core/cldr/es_PE.json +455 -450
  170. package/src/sap/ui/core/cldr/es_UY.json +479 -474
  171. package/src/sap/ui/core/cldr/es_VE.json +499 -494
  172. package/src/sap/ui/core/cldr/et.json +378 -320
  173. package/src/sap/ui/core/cldr/fa.json +104 -104
  174. package/src/sap/ui/core/cldr/fi.json +401 -315
  175. package/src/sap/ui/core/cldr/fr.json +391 -385
  176. package/src/sap/ui/core/cldr/fr_BE.json +391 -385
  177. package/src/sap/ui/core/cldr/fr_CA.json +499 -493
  178. package/src/sap/ui/core/cldr/fr_CH.json +334 -328
  179. package/src/sap/ui/core/cldr/fr_LU.json +391 -385
  180. package/src/sap/ui/core/cldr/he.json +291 -159
  181. package/src/sap/ui/core/cldr/hi.json +157 -128
  182. package/src/sap/ui/core/cldr/hr.json +514 -461
  183. package/src/sap/ui/core/cldr/hu.json +287 -257
  184. package/src/sap/ui/core/cldr/id.json +463 -416
  185. package/src/sap/ui/core/cldr/it.json +468 -413
  186. package/src/sap/ui/core/cldr/it_CH.json +468 -413
  187. package/src/sap/ui/core/cldr/ja.json +98 -61
  188. package/src/sap/ui/core/cldr/kk.json +631 -571
  189. package/src/sap/ui/core/cldr/ko.json +79 -71
  190. package/src/sap/ui/core/cldr/lt.json +361 -270
  191. package/src/sap/ui/core/cldr/lv.json +234 -242
  192. package/src/sap/ui/core/cldr/ms.json +463 -408
  193. package/src/sap/ui/core/cldr/nb.json +176 -143
  194. package/src/sap/ui/core/cldr/nl.json +463 -393
  195. package/src/sap/ui/core/cldr/nl_BE.json +463 -393
  196. package/src/sap/ui/core/cldr/pl.json +633 -344
  197. package/src/sap/ui/core/cldr/pt.json +447 -336
  198. package/src/sap/ui/core/cldr/pt_PT.json +488 -449
  199. package/src/sap/ui/core/cldr/ro.json +477 -383
  200. package/src/sap/ui/core/cldr/ru.json +367 -332
  201. package/src/sap/ui/core/cldr/ru_UA.json +361 -326
  202. package/src/sap/ui/core/cldr/sk.json +502 -537
  203. package/src/sap/ui/core/cldr/sl.json +168 -161
  204. package/src/sap/ui/core/cldr/sr.json +276 -225
  205. package/src/sap/ui/core/cldr/sr_Latn.json +972 -907
  206. package/src/sap/ui/core/cldr/sv.json +420 -346
  207. package/src/sap/ui/core/cldr/th.json +117 -94
  208. package/src/sap/ui/core/cldr/tr.json +413 -359
  209. package/src/sap/ui/core/cldr/uk.json +395 -368
  210. package/src/sap/ui/core/cldr/vi.json +392 -379
  211. package/src/sap/ui/core/cldr/zh_CN.json +91 -33
  212. package/src/sap/ui/core/cldr/zh_HK.json +90 -32
  213. package/src/sap/ui/core/cldr/zh_SG.json +90 -32
  214. package/src/sap/ui/core/cldr/zh_TW.json +75 -51
  215. package/src/sap/ui/core/date/CalendarWeekNumbering.js +6 -0
  216. package/src/sap/ui/core/date/Islamic.js +4 -4
  217. package/src/sap/ui/core/date/UI5Date.js +1 -1
  218. package/src/sap/ui/core/date/_Calendars.js +5 -2
  219. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  220. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  221. package/src/sap/ui/core/dnd/DragAndDrop.js +3 -2
  222. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  223. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  224. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  225. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  226. package/src/sap/ui/core/format/DateFormat.js +33 -21
  227. package/src/sap/ui/core/format/NumberFormat.js +3 -2
  228. package/src/sap/ui/core/format/TimezoneUtil.js +1 -1
  229. package/src/sap/ui/core/getCompatibilityVersion.js +2 -2
  230. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  231. package/src/sap/ui/core/library.js +128 -8
  232. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  233. package/src/sap/ui/core/message/Message.js +2 -2
  234. package/src/sap/ui/core/message/MessageManager.js +1 -1
  235. package/src/sap/ui/core/message/MessageParser.js +1 -1
  236. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  237. package/src/sap/ui/core/message/MessageType.js +2 -1
  238. package/src/sap/ui/core/messagebundle.properties +24 -0
  239. package/src/sap/ui/core/messagebundle_ar.properties +15 -3
  240. package/src/sap/ui/core/messagebundle_bg.properties +14 -2
  241. package/src/sap/ui/core/messagebundle_ca.properties +13 -1
  242. package/src/sap/ui/core/messagebundle_cs.properties +15 -3
  243. package/src/sap/ui/core/messagebundle_cy.properties +16 -4
  244. package/src/sap/ui/core/messagebundle_da.properties +15 -3
  245. package/src/sap/ui/core/messagebundle_de.properties +15 -3
  246. package/src/sap/ui/core/messagebundle_el.properties +16 -4
  247. package/src/sap/ui/core/messagebundle_en.properties +12 -0
  248. package/src/sap/ui/core/messagebundle_en_GB.properties +16 -4
  249. package/src/sap/ui/core/messagebundle_es.properties +15 -3
  250. package/src/sap/ui/core/messagebundle_es_MX.properties +15 -3
  251. package/src/sap/ui/core/messagebundle_et.properties +15 -3
  252. package/src/sap/ui/core/messagebundle_fi.properties +15 -3
  253. package/src/sap/ui/core/messagebundle_fr.properties +15 -3
  254. package/src/sap/ui/core/messagebundle_fr_CA.properties +14 -2
  255. package/src/sap/ui/core/messagebundle_hi.properties +16 -4
  256. package/src/sap/ui/core/messagebundle_hr.properties +14 -2
  257. package/src/sap/ui/core/messagebundle_hu.properties +16 -4
  258. package/src/sap/ui/core/messagebundle_id.properties +15 -3
  259. package/src/sap/ui/core/messagebundle_it.properties +17 -5
  260. package/src/sap/ui/core/messagebundle_iw.properties +15 -3
  261. package/src/sap/ui/core/messagebundle_ja.properties +25 -13
  262. package/src/sap/ui/core/messagebundle_kk.properties +15 -3
  263. package/src/sap/ui/core/messagebundle_ko.properties +14 -2
  264. package/src/sap/ui/core/messagebundle_lt.properties +15 -3
  265. package/src/sap/ui/core/messagebundle_lv.properties +15 -3
  266. package/src/sap/ui/core/messagebundle_mk.properties +352 -0
  267. package/src/sap/ui/core/messagebundle_ms.properties +15 -3
  268. package/src/sap/ui/core/messagebundle_nl.properties +15 -3
  269. package/src/sap/ui/core/messagebundle_no.properties +14 -2
  270. package/src/sap/ui/core/messagebundle_pl.properties +15 -3
  271. package/src/sap/ui/core/messagebundle_pt.properties +15 -3
  272. package/src/sap/ui/core/messagebundle_pt_PT.properties +14 -2
  273. package/src/sap/ui/core/messagebundle_ro.properties +15 -3
  274. package/src/sap/ui/core/messagebundle_ru.properties +15 -3
  275. package/src/sap/ui/core/messagebundle_sh.properties +43 -31
  276. package/src/sap/ui/core/messagebundle_sk.properties +16 -4
  277. package/src/sap/ui/core/messagebundle_sl.properties +15 -3
  278. package/src/sap/ui/core/messagebundle_sv.properties +22 -10
  279. package/src/sap/ui/core/messagebundle_th.properties +15 -3
  280. package/src/sap/ui/core/messagebundle_tr.properties +15 -3
  281. package/src/sap/ui/core/messagebundle_uk.properties +18 -6
  282. package/src/sap/ui/core/messagebundle_vi.properties +18 -6
  283. package/src/sap/ui/core/messagebundle_zh_CN.properties +15 -3
  284. package/src/sap/ui/core/messagebundle_zh_TW.properties +15 -3
  285. package/src/sap/ui/core/mvc/Controller.js +22 -16
  286. package/src/sap/ui/core/mvc/ControllerExtensionProvider.js +1 -1
  287. package/src/sap/ui/core/mvc/EventHandlerResolver.js +5 -15
  288. package/src/sap/ui/core/mvc/HTMLView.js +2 -2
  289. package/src/sap/ui/core/mvc/JSONView.js +4 -1
  290. package/src/sap/ui/core/mvc/JSONViewRenderer.js +1 -0
  291. package/src/sap/ui/core/mvc/JSView.js +1 -1
  292. package/src/sap/ui/core/mvc/OverrideExecution.js +4 -4
  293. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  294. package/src/sap/ui/core/mvc/View.js +25 -15
  295. package/src/sap/ui/core/mvc/ViewType.js +2 -0
  296. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  297. package/src/sap/ui/core/plugin/DeclarativeSupport.js +2 -1
  298. package/src/sap/ui/core/plugin/LessSupport.js +3 -1
  299. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  300. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  301. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  302. package/src/sap/ui/core/routing/Router.js +2 -4
  303. package/src/sap/ui/core/routing/Target.js +1 -3
  304. package/src/sap/ui/core/routing/Targets.js +2 -3
  305. package/src/sap/ui/core/routing/Views.js +2 -3
  306. package/src/sap/ui/core/routing/async/Target.js +1 -1
  307. package/src/sap/ui/core/rules/Config.support.js +11 -17
  308. package/src/sap/ui/core/search/OpenSearchProvider.js +2 -1
  309. package/src/sap/ui/core/search/SearchProvider.js +2 -1
  310. package/src/sap/ui/core/service/Service.js +1 -1
  311. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  312. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  313. package/src/sap/ui/core/support/Hotkeys.js +5 -3
  314. package/src/sap/ui/core/support/Plugin.js +1 -1
  315. package/src/sap/ui/core/support/RuleEngineOpaExtension.js +1 -3
  316. package/src/sap/ui/core/support/Support.js +3 -5
  317. package/src/sap/ui/core/support/ToolsAPI.js +15 -11
  318. package/src/sap/ui/core/support/plugins/ControlTree.js +2 -2
  319. package/src/sap/ui/core/support/plugins/Interaction.js +4 -4
  320. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  321. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  322. package/src/sap/ui/core/support/plugins/Selector.js +7 -5
  323. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  324. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  325. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  326. package/src/sap/ui/core/support/techinfo/TechnicalInfo.js +3 -1
  327. package/src/sap/ui/core/syncStyleClass.js +2 -2
  328. package/src/sap/ui/core/themes/base/fonts/SAP-icons.ttf +0 -0
  329. package/src/sap/ui/core/themes/base/fonts/SAP-icons.woff2 +0 -0
  330. package/src/sap/ui/core/themes/base/global.less +9 -9
  331. package/src/sap/ui/core/theming/Parameters.js +18 -19
  332. package/src/sap/ui/core/theming/ThemeManager.js +23 -4
  333. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  334. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  335. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  336. package/src/sap/ui/core/tmpl/Template.js +1 -1
  337. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  338. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  339. package/src/sap/ui/core/util/Export.js +1 -1
  340. package/src/sap/ui/core/util/ExportCell.js +1 -1
  341. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  342. package/src/sap/ui/core/util/ExportRow.js +1 -1
  343. package/src/sap/ui/core/util/ExportType.js +1 -1
  344. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  345. package/src/sap/ui/core/util/File.js +1 -1
  346. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  347. package/src/sap/ui/core/util/MockServer.js +1 -1
  348. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  349. package/src/sap/ui/core/util/XMLPreprocessor.js +3 -0
  350. package/src/sap/ui/core/util/_LocalizationHelper.js +122 -0
  351. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  352. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  353. package/src/sap/ui/core/util/serializer/ViewSerializer.js +4 -4
  354. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  355. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  356. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  357. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  358. package/src/sap/ui/core/webc/WebComponent.js +1 -1
  359. package/src/sap/ui/core/webc/WebComponentMetadata.js +1 -1
  360. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  361. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  362. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  363. package/src/sap/ui/debug/ControlTree.js +1 -1
  364. package/src/sap/ui/debug/DebugEnv.js +29 -7
  365. package/src/sap/ui/debug/PropertyList.js +1 -1
  366. package/src/sap/ui/model/ClientListBinding.js +9 -4
  367. package/src/sap/ui/model/ClientModel.js +1 -1
  368. package/src/sap/ui/model/ClientTreeBinding.js +9 -4
  369. package/src/sap/ui/model/CompositeDataState.js +1 -1
  370. package/src/sap/ui/model/CompositeType.js +1 -1
  371. package/src/sap/ui/model/DataState.js +2 -2
  372. package/src/sap/ui/model/Filter.js +39 -1
  373. package/src/sap/ui/model/FilterProcessor.js +15 -5
  374. package/src/sap/ui/model/ListBinding.js +5 -0
  375. package/src/sap/ui/model/ManagedObjectBindingSupport.js +4 -4
  376. package/src/sap/ui/model/MetaModel.js +1 -1
  377. package/src/sap/ui/model/Model.js +14 -8
  378. package/src/sap/ui/model/SelectionModel.js +1 -1
  379. package/src/sap/ui/model/SimpleType.js +1 -1
  380. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  381. package/src/sap/ui/model/TreeBinding.js +3 -0
  382. package/src/sap/ui/model/Type.js +1 -1
  383. package/src/sap/ui/model/analytics/AnalyticalBinding.js +3 -1
  384. package/src/sap/ui/model/json/JSONListBinding.js +3 -1
  385. package/src/sap/ui/model/json/JSONModel.js +1 -1
  386. package/src/sap/ui/model/json/JSONTreeBinding.js +3 -2
  387. package/src/sap/ui/model/message/MessageListBinding.js +3 -0
  388. package/src/sap/ui/model/message/MessageModel.js +1 -1
  389. package/src/sap/ui/model/odata/AnnotationHelper.js +9 -3
  390. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  391. package/src/sap/ui/model/odata/ODataListBinding.js +8 -2
  392. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  393. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  394. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  395. package/src/sap/ui/model/odata/ODataModel.js +9 -5
  396. package/src/sap/ui/model/odata/ODataPropertyBinding.js +1 -2
  397. package/src/sap/ui/model/odata/ODataTreeBinding.js +2 -0
  398. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +9 -14
  399. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  400. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  401. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  402. package/src/sap/ui/model/odata/type/Date.js +1 -1
  403. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  404. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  405. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  406. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
  407. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  408. package/src/sap/ui/model/odata/type/Double.js +1 -1
  409. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  410. package/src/sap/ui/model/odata/type/Int.js +1 -1
  411. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  412. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  413. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  414. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  415. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  416. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  417. package/src/sap/ui/model/odata/type/Single.js +1 -1
  418. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  419. package/src/sap/ui/model/odata/type/String.js +1 -1
  420. package/src/sap/ui/model/odata/type/Time.js +1 -1
  421. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  422. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  423. package/src/sap/ui/model/odata/v2/Context.js +1 -1
  424. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  425. package/src/sap/ui/model/odata/v2/ODataListBinding.js +40 -15
  426. package/src/sap/ui/model/odata/v2/ODataModel.js +26 -62
  427. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +38 -4
  428. package/src/sap/ui/model/odata/v4/Context.js +81 -7
  429. package/src/sap/ui/model/odata/v4/ODataBinding.js +3 -0
  430. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +1 -1
  431. package/src/sap/ui/model/odata/v4/ODataListBinding.js +217 -75
  432. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +2 -2
  433. package/src/sap/ui/model/odata/v4/ODataModel.js +6 -6
  434. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +1 -1
  435. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +406 -199
  436. package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +12 -7
  437. package/src/sap/ui/model/odata/v4/lib/_Cache.js +53 -30
  438. package/src/sap/ui/model/odata/v4/lib/_Helper.js +6 -4
  439. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +6 -6
  440. package/src/sap/ui/model/resource/ResourceModel.js +5 -6
  441. package/src/sap/ui/model/type/Boolean.js +1 -1
  442. package/src/sap/ui/model/type/Currency.js +1 -1
  443. package/src/sap/ui/model/type/Date.js +1 -1
  444. package/src/sap/ui/model/type/DateInterval.js +1 -1
  445. package/src/sap/ui/model/type/DateTime.js +1 -1
  446. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  447. package/src/sap/ui/model/type/FileSize.js +1 -1
  448. package/src/sap/ui/model/type/Float.js +1 -1
  449. package/src/sap/ui/model/type/Integer.js +1 -1
  450. package/src/sap/ui/model/type/String.js +1 -1
  451. package/src/sap/ui/model/type/Time.js +1 -1
  452. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  453. package/src/sap/ui/model/type/Unit.js +1 -1
  454. package/src/sap/ui/model/xml/XMLListBinding.js +3 -0
  455. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  456. package/src/sap/ui/model/xml/XMLTreeBinding.js +3 -0
  457. package/src/sap/ui/performance/BeaconRequest.js +2 -2
  458. package/src/sap/ui/performance/trace/Interaction.js +20 -16
  459. package/src/sap/ui/qunit/QUnitUtils.js +64 -45
  460. package/src/sap/ui/qunit/qunit-coverage.js +6 -0
  461. package/src/sap/ui/qunit/utils/ControlIterator.js +31 -1
  462. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  463. package/src/sap/ui/security/Security.js +128 -0
  464. package/src/sap/ui/test/BlanketReporter.js +2 -3
  465. package/src/sap/ui/test/BlanketReporterUI.view.xml +1 -1
  466. package/src/sap/ui/test/BranchTracking.js +2 -3
  467. package/src/sap/ui/test/ModuleTracking.js +48 -20
  468. package/src/sap/ui/test/OpaExtension.js +3 -3
  469. package/src/sap/ui/test/OpaPlugin.js +16 -6
  470. package/src/sap/ui/test/TestUtils.js +7 -4
  471. package/src/sap/ui/test/_BrowserLogCollector.js +1 -0
  472. package/src/sap/ui/test/_ControlFinder.js +3 -2
  473. package/src/sap/ui/test/_LogCollector.js +1 -0
  474. package/src/sap/ui/test/_UsageReport.js +115 -114
  475. package/src/sap/ui/test/actions/EnterText.js +24 -2
  476. package/src/sap/ui/test/autowaiter/WaiterBase.js +1 -0
  477. package/src/sap/ui/test/autowaiter/_moduleWaiter.js +1 -2
  478. package/src/sap/ui/test/autowaiter/_timeoutWaiter.js +1 -1
  479. package/src/sap/ui/test/generic/GenericTestCollection.js +5 -0
  480. package/src/sap/ui/test/generic/TestBase.js +1 -1
  481. package/src/sap/ui/test/generic/Utils.js +1 -1
  482. package/src/sap/ui/test/matchers/LabelFor.js +2 -12
  483. package/src/sap/ui/test/matchers/Matcher.js +1 -1
  484. package/src/sap/ui/test/pipelines/PipelineFactory.js +1 -0
  485. package/src/sap/ui/test/selectors/_Selector.js +1 -1
  486. package/src/sap/ui/util/Storage.js +1 -1
  487. package/src/ui5loader-autoconfig.js +84 -11
  488. package/test/sap/ui/core/demokit/sample/MessageManager/ODataBackendMessagesComp/manifest.json +3 -10
  489. package/test/sap/ui/core/demokit/sample/MessageManager/ODataBackendMessagesComp/package.json +13 -0
  490. package/test/sap/ui/core/demokit/sample/MessageManager/ODataBackendMessagesComp/ui5.yaml +11 -0
  491. package/test/sap/ui/core/demokit/sample/RoutingNestedComponent/localService/mockserver.js +3 -4
  492. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/ChartAnnotation.fragment.xml +7 -7
  493. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/Component.js +2 -3
  494. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/Detail.view.xml +12 -13
  495. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/Facets.fragment.xml +4 -4
  496. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/Field.fragment.xml +8 -8
  497. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/FormFacet.fragment.xml +3 -5
  498. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/LabeledField.fragment.xml +3 -3
  499. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/Table.fragment.xml +10 -10
  500. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/TableFacet.fragment.xml +3 -3
  501. package/test/sap/ui/core/demokit/sample/ViewTemplate/scenario/extension/HeaderInfo.fragment.xml +1 -1
  502. package/test/sap/ui/core/demokit/sample/ViewTemplate/tiny/Field.fragment.xml +2 -2
  503. package/test/sap/ui/core/demokit/sample/ViewTemplate/tiny/Template.view.xml +19 -21
  504. package/test/sap/ui/core/demokit/sample/ViewTemplate/types/TemplateV4.view.xml +2 -2
  505. package/test/sap/ui/core/demokit/sample/ViewTemplate/valuelist/Component.js +2 -3
  506. package/test/sap/ui/core/demokit/sample/common/SandboxModelHelper.js +2 -3
  507. package/test/sap/ui/core/demokit/sample/common/ValueHelp.js +2 -3
  508. package/test/sap/ui/core/demokit/sample/common/pages/Any.js +7 -8
  509. package/test/sap/ui/core/demokit/sample/matcher/BindingPath/manifest.json +3 -11
  510. package/test/sap/ui/core/demokit/sample/matcher/BindingPath/package.json +13 -0
  511. package/test/sap/ui/core/demokit/sample/matcher/BindingPath/ui5.yaml +11 -0
  512. package/test/sap/ui/core/demokit/sample/matcher/Descendant/Component.js +1 -1
  513. package/test/sap/ui/core/demokit/sample/matcher/Descendant/manifest.json +3 -11
  514. package/test/sap/ui/core/demokit/sample/matcher/Descendant/package.json +13 -0
  515. package/test/sap/ui/core/demokit/sample/matcher/Descendant/ui5.yaml +11 -0
  516. package/test/sap/ui/core/demokit/sample/matcher/I18NText/manifest.json +3 -11
  517. package/test/sap/ui/core/demokit/sample/matcher/I18NText/package.json +13 -0
  518. package/test/sap/ui/core/demokit/sample/matcher/I18NText/ui5.yaml +11 -0
  519. package/test/sap/ui/core/demokit/sample/matcher/LabelFor/manifest.json +3 -11
  520. package/test/sap/ui/core/demokit/sample/matcher/LabelFor/package.json +13 -0
  521. package/test/sap/ui/core/demokit/sample/matcher/LabelFor/ui5.yaml +11 -0
  522. package/test/sap/ui/core/demokit/sample/odata/v4/Ancestry/Main.controller.js +15 -6
  523. package/test/sap/ui/core/demokit/sample/odata/v4/DataAggregation/DataAggregation.controller.js +2 -3
  524. package/test/sap/ui/core/demokit/sample/odata/v4/FlatDataAggregation/FlatDataAggregation.controller.js +3 -4
  525. package/test/sap/ui/core/demokit/sample/odata/v4/HierarchyBindAction/Main.controller.js +39 -16
  526. package/test/sap/ui/core/demokit/sample/odata/v4/HierarchyBindAction/Main.view.xml +18 -21
  527. package/test/sap/ui/core/demokit/sample/odata/v4/HierarchyBindAction/data/all.json +509 -395
  528. package/test/sap/ui/core/demokit/sample/odata/v4/HierarchyBindAction/data/metadata.xml +586 -422
  529. package/test/sap/ui/core/demokit/sample/odata/v4/HierarchyBindAction/manifest.json +1 -1
  530. package/test/sap/ui/core/demokit/sample/odata/v4/LateProperties/Main.controller.js +2 -3
  531. package/test/sap/ui/core/demokit/sample/odata/v4/ListBindingTemplate/Facets.fragment.xml +22 -23
  532. package/test/sap/ui/core/demokit/sample/odata/v4/ListBindingTemplate/FormattedText.fragment.xml +2 -3
  533. package/test/sap/ui/core/demokit/sample/odata/v4/ListBindingTemplate/Main.view.xml +7 -7
  534. package/test/sap/ui/core/demokit/sample/odata/v4/MultipleInlineCreationRowsGrid/Main.controller.js +0 -3
  535. package/test/sap/ui/core/demokit/sample/odata/v4/RecursiveHierarchy/RecursiveHierarchy.controller.js +54 -9
  536. package/test/sap/ui/core/demokit/sample/odata/v4/RecursiveHierarchy/RecursiveHierarchy.view.xml +34 -9
  537. package/test/sap/ui/core/demokit/sample/odata/v4/RecursiveHierarchy/SandboxModel.js +156 -23
  538. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/Main.view.xml +3 -2
  539. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersTemplate/Facets.fragment.xml +22 -23
  540. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersTemplate/FormattedText.fragment.xml +2 -3
  541. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersTemplate/Main.view.xml +5 -5
  542. package/test/sap/ui/core/demokit/sample/odata/v4/ServerDrivenPaging/Main.controller.js +2 -3
  543. package/test/sap/ui/core/demokit/tutorial/databinding/01/Component.js +9 -25
  544. package/test/sap/ui/core/demokit/tutorial/databinding/01/manifest.json +20 -0
  545. package/test/sap/ui/core/demokit/tutorial/databinding/01/ui5.yaml +2 -2
  546. package/test/sap/ui/core/demokit/tutorial/databinding/01/webapp/manifest.json +5 -0
  547. package/test/sap/ui/core/demokit/tutorial/databinding/02/Component.js +9 -25
  548. package/test/sap/ui/core/demokit/tutorial/databinding/02/manifest.json +20 -0
  549. package/test/sap/ui/core/demokit/tutorial/databinding/02/ui5.yaml +2 -2
  550. package/test/sap/ui/core/demokit/tutorial/databinding/02/webapp/manifest.json +5 -0
  551. package/test/sap/ui/core/demokit/tutorial/databinding/03/Component.js +9 -25
  552. package/test/sap/ui/core/demokit/tutorial/databinding/03/manifest.json +20 -0
  553. package/test/sap/ui/core/demokit/tutorial/databinding/03/ui5.yaml +2 -2
  554. package/test/sap/ui/core/demokit/tutorial/databinding/03/webapp/manifest.json +5 -0
  555. package/test/sap/ui/core/demokit/tutorial/databinding/04/Component.js +9 -26
  556. package/test/sap/ui/core/demokit/tutorial/databinding/04/manifest.json +21 -0
  557. package/test/sap/ui/core/demokit/tutorial/databinding/04/ui5.yaml +2 -2
  558. package/test/sap/ui/core/demokit/tutorial/databinding/04/webapp/manifest.json +5 -0
  559. package/test/sap/ui/core/demokit/tutorial/databinding/05/Component.js +9 -26
  560. package/test/sap/ui/core/demokit/tutorial/databinding/05/manifest.json +21 -0
  561. package/test/sap/ui/core/demokit/tutorial/databinding/05/ui5.yaml +2 -2
  562. package/test/sap/ui/core/demokit/tutorial/databinding/05/webapp/manifest.json +5 -0
  563. package/test/sap/ui/core/demokit/tutorial/databinding/06/Component.js +9 -27
  564. package/test/sap/ui/core/demokit/tutorial/databinding/06/manifest.json +22 -0
  565. package/test/sap/ui/core/demokit/tutorial/databinding/06/ui5.yaml +2 -2
  566. package/test/sap/ui/core/demokit/tutorial/databinding/06/webapp/manifest.json +5 -0
  567. package/test/sap/ui/core/demokit/tutorial/databinding/07/Component.js +9 -28
  568. package/test/sap/ui/core/demokit/tutorial/databinding/07/manifest.json +23 -0
  569. package/test/sap/ui/core/demokit/tutorial/databinding/07/ui5.yaml +2 -2
  570. package/test/sap/ui/core/demokit/tutorial/databinding/07/webapp/manifest.json +5 -0
  571. package/test/sap/ui/core/demokit/tutorial/databinding/08/Component.js +9 -28
  572. package/test/sap/ui/core/demokit/tutorial/databinding/08/manifest.json +23 -0
  573. package/test/sap/ui/core/demokit/tutorial/databinding/08/ui5.yaml +2 -2
  574. package/test/sap/ui/core/demokit/tutorial/databinding/08/webapp/manifest.json +5 -0
  575. package/test/sap/ui/core/demokit/tutorial/databinding/09/Component.js +9 -29
  576. package/test/sap/ui/core/demokit/tutorial/databinding/09/manifest.json +24 -0
  577. package/test/sap/ui/core/demokit/tutorial/databinding/09/ui5.yaml +2 -2
  578. package/test/sap/ui/core/demokit/tutorial/databinding/09/webapp/manifest.json +5 -0
  579. package/test/sap/ui/core/demokit/tutorial/databinding/10/Component.js +9 -29
  580. package/test/sap/ui/core/demokit/tutorial/databinding/10/manifest.json +24 -0
  581. package/test/sap/ui/core/demokit/tutorial/databinding/10/ui5.yaml +2 -2
  582. package/test/sap/ui/core/demokit/tutorial/databinding/10/webapp/manifest.json +5 -0
  583. package/test/sap/ui/core/demokit/tutorial/databinding/11/Component.js +9 -29
  584. package/test/sap/ui/core/demokit/tutorial/databinding/11/manifest.json +24 -0
  585. package/test/sap/ui/core/demokit/tutorial/databinding/11/ui5.yaml +2 -2
  586. package/test/sap/ui/core/demokit/tutorial/databinding/11/webapp/manifest.json +5 -0
  587. package/test/sap/ui/core/demokit/tutorial/databinding/12/Component.js +9 -30
  588. package/test/sap/ui/core/demokit/tutorial/databinding/12/manifest.json +25 -0
  589. package/test/sap/ui/core/demokit/tutorial/databinding/12/ui5.yaml +2 -2
  590. package/test/sap/ui/core/demokit/tutorial/databinding/12/webapp/manifest.json +5 -0
  591. package/test/sap/ui/core/demokit/tutorial/databinding/13/Component.js +9 -30
  592. package/test/sap/ui/core/demokit/tutorial/databinding/13/manifest.json +25 -0
  593. package/test/sap/ui/core/demokit/tutorial/databinding/13/ui5.yaml +2 -2
  594. package/test/sap/ui/core/demokit/tutorial/databinding/13/webapp/manifest.json +5 -0
  595. package/test/sap/ui/core/demokit/tutorial/databinding/14/Component.js +9 -30
  596. package/test/sap/ui/core/demokit/tutorial/databinding/14/manifest.json +25 -0
  597. package/test/sap/ui/core/demokit/tutorial/databinding/14/ui5.yaml +2 -2
  598. package/test/sap/ui/core/demokit/tutorial/databinding/14/webapp/manifest.json +5 -0
  599. package/test/sap/ui/core/demokit/tutorial/databinding/15/Component.js +9 -32
  600. package/test/sap/ui/core/demokit/tutorial/databinding/15/manifest.json +27 -0
  601. package/test/sap/ui/core/demokit/tutorial/databinding/15/ui5.yaml +2 -2
  602. package/test/sap/ui/core/demokit/tutorial/databinding/15/webapp/manifest.json +5 -0
  603. package/test/sap/ui/core/demokit/tutorial/mockserver/01/Component.js +9 -30
  604. package/test/sap/ui/core/demokit/tutorial/mockserver/01/manifest.json +24 -0
  605. package/test/sap/ui/core/demokit/tutorial/mockserver/01/ui5.yaml +2 -2
  606. package/test/sap/ui/core/demokit/tutorial/mockserver/02/Component.js +9 -33
  607. package/test/sap/ui/core/demokit/tutorial/mockserver/02/manifest.json +27 -0
  608. package/test/sap/ui/core/demokit/tutorial/mockserver/02/ui5.yaml +2 -2
  609. package/test/sap/ui/core/demokit/tutorial/mockserver/03/Component.js +9 -33
  610. package/test/sap/ui/core/demokit/tutorial/mockserver/03/manifest.json +27 -0
  611. package/test/sap/ui/core/demokit/tutorial/mockserver/03/ui5.yaml +2 -2
  612. package/test/sap/ui/core/demokit/tutorial/mockserver/04/Component.js +9 -33
  613. package/test/sap/ui/core/demokit/tutorial/mockserver/04/manifest.json +27 -0
  614. package/test/sap/ui/core/demokit/tutorial/mockserver/04/ui5.yaml +2 -2
  615. package/test/sap/ui/core/demokit/tutorial/navigation/01/Component.js +9 -33
  616. package/test/sap/ui/core/demokit/tutorial/navigation/01/manifest.json +28 -0
  617. package/test/sap/ui/core/demokit/tutorial/navigation/01/ui5.yaml +2 -2
  618. package/test/sap/ui/core/demokit/tutorial/navigation/02/Component.js +9 -35
  619. package/test/sap/ui/core/demokit/tutorial/navigation/02/manifest.json +30 -0
  620. package/test/sap/ui/core/demokit/tutorial/navigation/02/ui5.yaml +2 -2
  621. package/test/sap/ui/core/demokit/tutorial/navigation/03/Component.js +9 -37
  622. package/test/sap/ui/core/demokit/tutorial/navigation/03/manifest.json +32 -0
  623. package/test/sap/ui/core/demokit/tutorial/navigation/03/ui5.yaml +2 -2
  624. package/test/sap/ui/core/demokit/tutorial/navigation/04/Component.js +9 -38
  625. package/test/sap/ui/core/demokit/tutorial/navigation/04/manifest.json +33 -0
  626. package/test/sap/ui/core/demokit/tutorial/navigation/04/ui5.yaml +2 -2
  627. package/test/sap/ui/core/demokit/tutorial/navigation/05/Component.js +9 -38
  628. package/test/sap/ui/core/demokit/tutorial/navigation/05/manifest.json +33 -0
  629. package/test/sap/ui/core/demokit/tutorial/navigation/05/ui5.yaml +2 -2
  630. package/test/sap/ui/core/demokit/tutorial/navigation/06/Component.js +9 -40
  631. package/test/sap/ui/core/demokit/tutorial/navigation/06/manifest.json +35 -0
  632. package/test/sap/ui/core/demokit/tutorial/navigation/06/ui5.yaml +2 -2
  633. package/test/sap/ui/core/demokit/tutorial/navigation/07/Component.js +9 -42
  634. package/test/sap/ui/core/demokit/tutorial/navigation/07/manifest.json +37 -0
  635. package/test/sap/ui/core/demokit/tutorial/navigation/07/ui5.yaml +2 -2
  636. package/test/sap/ui/core/demokit/tutorial/navigation/08/Component.js +9 -45
  637. package/test/sap/ui/core/demokit/tutorial/navigation/08/manifest.json +40 -0
  638. package/test/sap/ui/core/demokit/tutorial/navigation/08/ui5.yaml +2 -2
  639. package/test/sap/ui/core/demokit/tutorial/navigation/09/Component.js +9 -45
  640. package/test/sap/ui/core/demokit/tutorial/navigation/09/manifest.json +40 -0
  641. package/test/sap/ui/core/demokit/tutorial/navigation/09/ui5.yaml +2 -2
  642. package/test/sap/ui/core/demokit/tutorial/navigation/10/Component.js +9 -47
  643. package/test/sap/ui/core/demokit/tutorial/navigation/10/manifest.json +42 -0
  644. package/test/sap/ui/core/demokit/tutorial/navigation/10/ui5.yaml +2 -2
  645. package/test/sap/ui/core/demokit/tutorial/navigation/11/Component.js +9 -52
  646. package/test/sap/ui/core/demokit/tutorial/navigation/11/manifest.json +47 -0
  647. package/test/sap/ui/core/demokit/tutorial/navigation/11/ui5.yaml +2 -2
  648. package/test/sap/ui/core/demokit/tutorial/navigation/12/Component.js +9 -52
  649. package/test/sap/ui/core/demokit/tutorial/navigation/12/manifest.json +47 -0
  650. package/test/sap/ui/core/demokit/tutorial/navigation/12/ui5.yaml +2 -2
  651. package/test/sap/ui/core/demokit/tutorial/navigation/13/Component.js +9 -52
  652. package/test/sap/ui/core/demokit/tutorial/navigation/13/manifest.json +47 -0
  653. package/test/sap/ui/core/demokit/tutorial/navigation/13/ui5.yaml +2 -2
  654. package/test/sap/ui/core/demokit/tutorial/navigation/14/Component.js +9 -52
  655. package/test/sap/ui/core/demokit/tutorial/navigation/14/manifest.json +47 -0
  656. package/test/sap/ui/core/demokit/tutorial/navigation/14/ui5.yaml +2 -2
  657. package/test/sap/ui/core/demokit/tutorial/navigation/15/Component.js +9 -52
  658. package/test/sap/ui/core/demokit/tutorial/navigation/15/manifest.json +47 -0
  659. package/test/sap/ui/core/demokit/tutorial/navigation/15/ui5.yaml +2 -2
  660. package/test/sap/ui/core/demokit/tutorial/navigation/16/Component.js +9 -52
  661. package/test/sap/ui/core/demokit/tutorial/navigation/16/manifest.json +47 -0
  662. package/test/sap/ui/core/demokit/tutorial/navigation/16/ui5.yaml +2 -2
  663. package/test/sap/ui/core/demokit/tutorial/navigation/17/Component.js +9 -52
  664. package/test/sap/ui/core/demokit/tutorial/navigation/17/manifest.json +47 -0
  665. package/test/sap/ui/core/demokit/tutorial/navigation/17/ui5.yaml +2 -2
  666. package/test/sap/ui/core/demokit/tutorial/odatav4/01/Component.js +3 -27
  667. package/test/sap/ui/core/demokit/tutorial/odatav4/01/manifest.json +28 -0
  668. package/test/sap/ui/core/demokit/tutorial/odatav4/01/ui5.yaml +2 -2
  669. package/test/sap/ui/core/demokit/tutorial/odatav4/02/Component.js +3 -27
  670. package/test/sap/ui/core/demokit/tutorial/odatav4/02/manifest.json +28 -0
  671. package/test/sap/ui/core/demokit/tutorial/odatav4/02/ui5.yaml +2 -2
  672. package/test/sap/ui/core/demokit/tutorial/odatav4/03/Component.js +3 -27
  673. package/test/sap/ui/core/demokit/tutorial/odatav4/03/manifest.json +28 -0
  674. package/test/sap/ui/core/demokit/tutorial/odatav4/03/ui5.yaml +2 -2
  675. package/test/sap/ui/core/demokit/tutorial/odatav4/04/Component.js +3 -27
  676. package/test/sap/ui/core/demokit/tutorial/odatav4/04/manifest.json +28 -0
  677. package/test/sap/ui/core/demokit/tutorial/odatav4/04/ui5.yaml +2 -2
  678. package/test/sap/ui/core/demokit/tutorial/odatav4/05/Component.js +3 -27
  679. package/test/sap/ui/core/demokit/tutorial/odatav4/05/manifest.json +28 -0
  680. package/test/sap/ui/core/demokit/tutorial/odatav4/05/ui5.yaml +2 -2
  681. package/test/sap/ui/core/demokit/tutorial/odatav4/06/Component.js +3 -27
  682. package/test/sap/ui/core/demokit/tutorial/odatav4/06/manifest.json +28 -0
  683. package/test/sap/ui/core/demokit/tutorial/odatav4/06/ui5.yaml +2 -2
  684. package/test/sap/ui/core/demokit/tutorial/odatav4/07/Component.js +3 -27
  685. package/test/sap/ui/core/demokit/tutorial/odatav4/07/manifest.json +28 -0
  686. package/test/sap/ui/core/demokit/tutorial/odatav4/07/ui5.yaml +2 -2
  687. package/test/sap/ui/core/demokit/tutorial/odatav4/08/Component.js +3 -27
  688. package/test/sap/ui/core/demokit/tutorial/odatav4/08/manifest.json +28 -0
  689. package/test/sap/ui/core/demokit/tutorial/odatav4/08/ui5.yaml +2 -2
  690. package/test/sap/ui/core/demokit/tutorial/odatav4/09/Component.js +3 -27
  691. package/test/sap/ui/core/demokit/tutorial/odatav4/09/manifest.json +28 -0
  692. package/test/sap/ui/core/demokit/tutorial/odatav4/09/ui5.yaml +2 -2
  693. package/test/sap/ui/core/demokit/tutorial/odatav4/10/Component.js +3 -27
  694. package/test/sap/ui/core/demokit/tutorial/odatav4/10/manifest.json +28 -0
  695. package/test/sap/ui/core/demokit/tutorial/odatav4/10/ui5.yaml +2 -2
  696. package/test/sap/ui/core/demokit/tutorial/odatav4/11/Component.js +3 -27
  697. package/test/sap/ui/core/demokit/tutorial/odatav4/11/manifest.json +28 -0
  698. package/test/sap/ui/core/demokit/tutorial/odatav4/11/ui5.yaml +2 -2
  699. package/test/sap/ui/core/demokit/tutorial/troubleshooting/01/Component.js +9 -29
  700. package/test/sap/ui/core/demokit/tutorial/troubleshooting/01/manifest.json +25 -0
  701. package/test/sap/ui/core/demokit/tutorial/troubleshooting/01/ui5.yaml +2 -2
  702. package/test/sap/ui/core/internal/samples/odata/v2/SalesOrders/Component.js +2 -3
  703. package/test/sap/ui/core/internal/samples/odata/v2/SalesOrders/Main.view.xml +1 -1
  704. package/test/sap/ui/core/internal/samples/odata/v2/SalesOrders/SandboxModel.js +2 -3
  705. package/test/sap/ui/core/qunit/ClientModel.qunit.js +28 -28
  706. package/test/sap/ui/core/qunit/CompositeBinding.qunit.js +18 -0
  707. package/test/sap/ui/core/qunit/ControlRenderer.qunit.js +4 -3
  708. package/test/sap/ui/core/qunit/Core.qunit.js +5 -14
  709. package/test/sap/ui/core/qunit/Core_libraryPreloadFiles.qunit.js +4 -4
  710. package/test/sap/ui/core/qunit/Core_libraryPreloadFiles_unavoidablyUsingEval.qunit.js +6 -6
  711. package/test/sap/ui/core/qunit/Core_unavoidablyUsingEval.qunit.js +31 -30
  712. package/test/sap/ui/core/qunit/DataState.qunit.js +7 -4
  713. package/test/sap/ui/core/qunit/DuplicateIds.qunit.js +3 -0
  714. package/test/sap/ui/core/qunit/DuplicateIds_noError.qunit.js +4 -0
  715. package/test/sap/ui/core/qunit/Element_metadata_renderer.qunit.js +6 -0
  716. package/test/sap/ui/core/qunit/ExpressionParser.qunit.js +144 -85
  717. package/test/sap/ui/core/qunit/HTML.qunit.js +87 -84
  718. package/test/sap/ui/core/qunit/InvisibleText.qunit.js +22 -1
  719. package/test/sap/ui/core/qunit/LRUPersistentCache.qunit.js +4 -4
  720. package/test/sap/ui/core/qunit/Lib.qunit.js +64 -1
  721. package/test/sap/ui/core/qunit/ListBinding.qunit.js +14 -1
  722. package/test/sap/ui/core/qunit/ManagedObject.qunit.js +90 -4
  723. package/test/sap/ui/core/qunit/ManagedObjectMetadata.qunit.js +41 -40
  724. package/test/sap/ui/core/qunit/ManagedObjectModel.qunit.js +2 -1
  725. package/test/sap/ui/core/qunit/{ManagedObject_noBoot.qunit.js → ManagedObject_BindingParser.qunit.js} +10 -9
  726. package/test/sap/ui/core/qunit/Object.qunit.js +36 -0
  727. package/test/sap/ui/core/qunit/RenderManager.qunit.js +86 -94
  728. package/test/sap/ui/core/qunit/ShortcutHints.qunit.js +11 -97
  729. package/test/sap/ui/core/qunit/StaticBinding.qunit.js +3 -0
  730. package/test/sap/ui/core/qunit/UIArea.qunit.js +34 -35
  731. package/test/sap/ui/core/qunit/analytics/AnalyticalTreeBindingAdapter.qunit.js +3 -0
  732. package/test/sap/ui/core/qunit/analytics/ODataModelAdapter.qunit.js +3 -0
  733. package/test/sap/ui/core/qunit/analytics/odata4analytics.qunit.js +3 -0
  734. package/test/sap/ui/core/qunit/app/DesignMode_controllerDeactivated.qunit.js +5 -6
  735. package/test/sap/ui/core/qunit/app/DesignMode_suppressedDeactivation.qunit.js +5 -6
  736. package/test/sap/ui/core/qunit/app/MessageListBinding.qunit.js +3 -0
  737. package/test/sap/ui/core/qunit/app/_createDesignModeTests_legacyAPIs.qunit.js +8 -10
  738. package/test/sap/ui/core/qunit/base/Config_cascade.qunit.js +2 -2
  739. package/test/sap/ui/core/qunit/base/i18n/Formatting.qunit.js +49 -30
  740. package/test/sap/ui/core/qunit/base/i18n/ResourceBundle.qunit.js +123 -10
  741. package/test/sap/ui/core/qunit/base/util/resolveReference.qunit.js +9 -0
  742. package/test/sap/ui/core/qunit/base/util/testdata/MyModule.js +5 -0
  743. package/test/sap/ui/core/qunit/bootstrap/BootstrapCustomBootTaskPreloadCss.beforeBootstrap.qunit.js +4 -2
  744. package/test/sap/ui/core/qunit/bootstrap/BootstrapMinimal.qunit.html +1 -0
  745. package/test/sap/ui/core/qunit/bootstrap/BootstrapPreload.qunit.js +9 -10
  746. package/test/sap/ui/core/qunit/bootstrap/BootstrapPreload_legacyAPIs.qunit.js +0 -2
  747. package/test/sap/ui/core/qunit/bootstrap/BootstrapWithinBody.qunit.html +2 -1
  748. package/test/sap/ui/core/qunit/bootstrap/BootstrapWithinHead.qunit.html +2 -1
  749. package/test/sap/ui/core/qunit/bootstrap/Configuration.qunit.js +122 -266
  750. package/test/sap/ui/core/qunit/bootstrap/ConfigurationFlexibility_LibConfigured.qunit.html +22 -0
  751. package/test/sap/ui/core/qunit/bootstrap/ConfigurationFlexibility_LibConfigured.qunit.js +22 -0
  752. package/test/sap/ui/core/qunit/bootstrap/ConfigurationFlexibility_LibLoaded.qunit.html +22 -0
  753. package/test/sap/ui/core/qunit/bootstrap/ConfigurationFlexibility_LibLoaded.qunit.js +16 -0
  754. package/test/sap/ui/core/qunit/bootstrap/ConfigurationFlexibility_LibNotLoaded.qunit.html +22 -0
  755. package/test/sap/ui/core/qunit/bootstrap/ConfigurationFlexibility_LibNotLoaded.qunit.js +14 -0
  756. package/test/sap/ui/core/qunit/bootstrap/ControlBehavior.qunit.js +110 -0
  757. package/test/sap/ui/core/qunit/bootstrap/PreloadCfg.qunit.js +4 -3
  758. package/test/sap/ui/core/qunit/bootstrap/ResourceRoot_ResourcesURL_Standard.qunit.html +1 -1
  759. package/test/sap/ui/core/qunit/bootstrap/ThemeVersion.beforeBootstrap.qunit.js +2 -3
  760. package/test/sap/ui/core/qunit/bootstrap/_checkCoreAndLibraryBooted.qunit.js +39 -34
  761. package/test/sap/ui/core/qunit/bootstrap/_checkCoreAndLibraryBooted_legacyAPIs.qunit.js +5 -1
  762. package/test/sap/ui/core/qunit/bootstrap/testsuite.bootstrap.qunit.js +51 -15
  763. package/test/sap/ui/core/qunit/compat_legacyAPIs/jquery-compat.qunit.html +23 -0
  764. package/test/sap/ui/core/qunit/compat_legacyAPIs/jquery-compat.qunit.js +1 -1
  765. package/test/sap/ui/core/qunit/compat_legacyAPIs/jquery.sap.stubs.qunit.js +16 -20
  766. package/test/sap/ui/core/qunit/compat_legacyAPIs/testsuite.compat.qunit.js +1 -4
  767. package/test/sap/ui/core/qunit/component/Component.qunit.js +100 -7
  768. package/test/sap/ui/core/qunit/component/Models.qunit.js +3 -1
  769. package/test/sap/ui/core/qunit/component/Preloading.qunit.js +8 -12
  770. package/test/sap/ui/core/qunit/component/UIComponent.qunit.js +8 -2
  771. package/test/sap/ui/core/qunit/component/testdata/routerPreloading/Component.js +23 -0
  772. package/test/sap/ui/core/qunit/component/testdata/routerPreloading/Main.view.xml +8 -0
  773. package/test/sap/ui/core/qunit/component/testdata/routerPreloading/manifest.json +34 -0
  774. package/test/sap/ui/core/qunit/component/testdata/targetsPreloading/Component.js +23 -0
  775. package/test/sap/ui/core/qunit/component/testdata/targetsPreloading/Main.view.xml +8 -0
  776. package/test/sap/ui/core/qunit/component/testdata/targetsPreloading/manifest.json +28 -0
  777. package/test/sap/ui/core/qunit/date/_Calendars.qunit.js +52 -0
  778. package/test/sap/ui/core/qunit/generic/legacy/ControlMemoryLeaks.qunit.js +18 -0
  779. package/test/sap/ui/core/qunit/generic/legacy/ControlMemoryLeaksUsingIterator.qunit.js +3 -4
  780. package/test/sap/ui/core/qunit/generic/legacy/DuplicateIdCheck.qunit.js +18 -0
  781. package/test/sap/ui/core/qunit/generic/legacy/SettersContextReturn.qunit.js +15 -0
  782. package/test/sap/ui/core/qunit/generic/testsuite.generic.qunit.js +21 -0
  783. package/test/sap/ui/core/qunit/gherkin/fixture/testHarnessAmbiguous.js +2 -3
  784. package/test/sap/ui/core/qunit/gherkin/fixture/testHarnessDuplicate.js +2 -3
  785. package/test/sap/ui/core/qunit/gherkin/fixture/testHarnessFailing.js +2 -3
  786. package/test/sap/ui/core/qunit/gherkin/opa5TestHarness.qunit.html +16 -0
  787. package/test/sap/ui/core/qunit/gherkin/opa5TestHarness.qunit.js +1 -1
  788. package/test/sap/ui/core/qunit/gherkin/qUnitTestHarness.qunit.html +16 -0
  789. package/test/sap/ui/core/qunit/gherkin/qUnitTestHarness.qunit.js +1 -1
  790. package/test/sap/ui/core/qunit/gherkin/testsuite.gherkin.qunit.js +3 -2
  791. package/test/sap/ui/core/qunit/i18n/Buddhist.qunit.js +3 -0
  792. package/test/sap/ui/core/qunit/i18n/GenericLocaleData.qunit.js +217 -114
  793. package/test/sap/ui/core/qunit/i18n/Islamic.qunit.js +7 -4
  794. package/test/sap/ui/core/qunit/i18n/Japanese.qunit.js +3 -0
  795. package/test/sap/ui/core/qunit/i18n/LocaleData.qunit.js +341 -7
  796. package/test/sap/ui/core/qunit/i18n/Persian.qunit.js +3 -0
  797. package/test/sap/ui/core/qunit/i18n/UniversalDate.qunit.js +3 -0
  798. package/test/sap/ui/core/qunit/i18n/UniversalDateUtils.qunit.js +10 -1
  799. package/test/sap/ui/core/qunit/i18n/helper/_timezones.js +17 -11
  800. package/test/sap/ui/core/qunit/i18n/testsuite.i18n.qunit.js +7 -1
  801. package/test/sap/ui/core/qunit/internal/1Ring.qunit.html +5 -1
  802. package/test/sap/ui/core/qunit/internal/1RingModels.qunit.html +2 -2
  803. package/test/sap/ui/core/qunit/internal/1RingModels.qunit.js +1 -0
  804. package/test/sap/ui/core/qunit/internal/AnnotationParser.qunit.html +1 -2
  805. package/test/sap/ui/core/qunit/internal/ODataV4.qunit.html +6 -1
  806. package/test/sap/ui/core/qunit/internal/testsuite.feature-odata-v4.qunit.js +2 -1
  807. package/test/sap/ui/core/qunit/jquery.sap.global-config.qunit.html +24 -0
  808. package/test/sap/ui/core/qunit/jquery.sap.global-config.qunit.js +12 -6
  809. package/test/sap/ui/core/qunit/jquery.sap.global-config_beforeBootstrap.qunit.js +1 -1
  810. package/test/sap/ui/core/qunit/json/JSONListBinding.qunit.js +30 -0
  811. package/test/sap/ui/core/qunit/loader/exposeAsAMDLoader.qunit.html +1 -0
  812. package/test/sap/ui/core/qunit/model/Binding.qunit.js +3 -0
  813. package/test/sap/ui/core/qunit/model/ClientListBinding.qunit.js +5 -2
  814. package/test/sap/ui/core/qunit/model/ClientPropertyBinding.qunit.js +3 -0
  815. package/test/sap/ui/core/qunit/model/ClientTreeBinding.qunit.js +5 -2
  816. package/test/sap/ui/core/qunit/model/ClientTreeBindingAdapter.qunit.js +6 -0
  817. package/test/sap/ui/core/qunit/model/CompositeDataState.qunit.js +3 -0
  818. package/test/sap/ui/core/qunit/model/Context.qunit.js +3 -0
  819. package/test/sap/ui/core/qunit/model/ContextBinding.qunit.js +3 -0
  820. package/test/sap/ui/core/qunit/model/Filter.qunit.js +49 -0
  821. package/test/sap/ui/core/qunit/model/FilterProcessor.qunit.js +68 -1
  822. package/test/sap/ui/core/qunit/model/ListBinding.qunit.js +23 -5
  823. package/test/sap/ui/core/qunit/model/Model.qunit.js +46 -2
  824. package/test/sap/ui/core/qunit/model/PropertyBinding.qunit.js +3 -0
  825. package/test/sap/ui/core/qunit/model/Sorter.qunit.js +3 -0
  826. package/test/sap/ui/core/qunit/model/TreeBinding.qunit.js +43 -3
  827. package/test/sap/ui/core/qunit/model/TreeBindingAdapter.qunit.js +3 -0
  828. package/test/sap/ui/core/qunit/mvc/Controller.qunit.js +107 -93
  829. package/test/sap/ui/core/qunit/mvc/View.qunit.js +3 -0
  830. package/test/sap/ui/core/qunit/mvc/XMLTemplateProcessor.qunit.js +17 -14
  831. package/test/sap/ui/core/qunit/mvc/XMLTemplateProcessorAsync.qunit.js +23 -12
  832. package/test/sap/ui/core/qunit/mvc/XMLTemplateProcessorRequireXML.qunit.js +29 -82
  833. package/test/sap/ui/core/qunit/mvc/XMLTemplateProcessorRequireXML_unavoidablySync.qunit.js +123 -0
  834. package/test/sap/ui/core/qunit/mvc/extensions/Controllerextensions.qunit.js +4 -0
  835. package/test/sap/ui/core/qunit/mvc/extensions/Controllerextensions_legacy.qunit.js +4 -0
  836. package/test/sap/ui/core/qunit/mvc/testsuite.mvc.qunit.js +16 -0
  837. package/test/sap/ui/core/qunit/mvc/viewprocessing/ViewProcessing.qunit.js +408 -419
  838. package/test/sap/ui/core/qunit/odata/AnnotationHelper.qunit.js +6 -4
  839. package/test/sap/ui/core/qunit/odata/ODataAnnotations.qunit.js +16 -0
  840. package/test/sap/ui/core/qunit/odata/ODataMetaModel.qunit.js +8 -1
  841. package/test/sap/ui/core/qunit/odata/ODataModel_legacyAPIs.qunit.js +22 -22
  842. package/test/sap/ui/core/qunit/odata/ODataTreeBindingAdapter.qunit.js +1 -1
  843. package/test/sap/ui/core/qunit/odata/ODataUtils.qunit.js +5 -1
  844. package/test/sap/ui/core/qunit/odata/type/DateTimeBase.qunit.js +4 -4
  845. package/test/sap/ui/core/qunit/odata/type/DateTimeWithTimezone.qunit.js +6 -6
  846. package/test/sap/ui/core/qunit/odata/type/Time.qunit.js +3 -4
  847. package/test/sap/ui/core/qunit/odata/type/TimeOfDay.qunit.js +4 -4
  848. package/test/sap/ui/core/qunit/odata/v2/ODataListBindingNoFakeService.qunit.js +52 -29
  849. package/test/sap/ui/core/qunit/odata/v2/ODataModel.integration.qunit.js +952 -292
  850. package/test/sap/ui/core/qunit/odata/v2/ODataModelNoFakeService.qunit.js +8 -15
  851. package/test/sap/ui/core/qunit/odata/v2/ODataPropertyBindingNoFakeService.qunit.js +6 -7
  852. package/test/sap/ui/core/qunit/odata/v2/ODataTreeBindingFlatNoFakeService.qunit.js +215 -1
  853. package/test/sap/ui/core/qunit/odata/v2/ODataTreeBindingNoFakeService.qunit.js +211 -20
  854. package/test/sap/ui/core/qunit/odata/v2/ODataV2Model.qunit.js +32 -36
  855. package/test/sap/ui/core/qunit/odata/v2/V2ODataModelDataState.qunit.js +3 -2
  856. package/test/sap/ui/core/qunit/odata/v4/Context.qunit.js +69 -2
  857. package/test/sap/ui/core/qunit/odata/v4/ODataBinding.qunit.js +19 -9
  858. package/test/sap/ui/core/qunit/odata/v4/ODataListBinding.qunit.js +601 -99
  859. package/test/sap/ui/core/qunit/odata/v4/ODataMetaModel.qunit.js +5 -5
  860. package/test/sap/ui/core/qunit/odata/v4/ODataModel.integration.qunit.js +1896 -407
  861. package/test/sap/ui/core/qunit/odata/v4/ODataModel.qunit.js +7 -5
  862. package/test/sap/ui/core/qunit/odata/v4/ODataModel.realOData.qunit.js +4 -4
  863. package/test/sap/ui/core/qunit/odata/v4/lib/_AggregationCache.qunit.js +909 -422
  864. package/test/sap/ui/core/qunit/odata/v4/lib/_AggregationHelper.qunit.js +21 -6
  865. package/test/sap/ui/core/qunit/odata/v4/lib/_Cache.qunit.js +104 -33
  866. package/test/sap/ui/core/qunit/odata/v4/lib/_Helper.qunit.js +8 -0
  867. package/test/sap/ui/core/qunit/odata/v4/lib/_MetadataRequestor.qunit.js +4 -4
  868. package/test/sap/ui/core/qunit/odata/v4/lib/_Requestor.qunit.js +9 -9
  869. package/test/sap/ui/core/qunit/odata/v4/lib/_V2MetadataConverter.qunit.js +3 -3
  870. package/test/sap/ui/core/qunit/odata/v4/lib/_V4MetadataConverter.qunit.js +3 -3
  871. package/test/sap/ui/core/qunit/opa/OpaPlugin.qunit.js +16 -0
  872. package/test/sap/ui/core/qunit/opa/_LogCollector.qunit.js +17 -9
  873. package/test/sap/ui/core/qunit/opa/actions/EnterText.qunit.js +66 -3
  874. package/test/sap/ui/core/qunit/opa/autowaiter/_cssAnimationWaiter.js +3 -3
  875. package/test/sap/ui/core/qunit/opa/autowaiter/_cssTransitionWaiter.js +3 -3
  876. package/test/sap/ui/core/qunit/opa/autowaiter/_jsAnimationWaiter.js +3 -3
  877. package/test/sap/ui/core/qunit/opa/autowaiter/_timeoutWaiter.js +11 -0
  878. package/test/sap/ui/core/qunit/opa/fixture/miniUI5Site.js +14 -8
  879. package/test/sap/ui/core/qunit/opa/fixture/uncaughtError.js +18 -12
  880. package/test/sap/ui/core/qunit/performance/BeaconRequest.qunit.js +18 -2
  881. package/test/sap/ui/core/qunit/performance/trace/FESR.qunit.js +11 -2
  882. package/test/sap/ui/core/qunit/performance/trace/Interaction.qunit.js +4 -7
  883. package/test/sap/ui/core/qunit/resource/ResourceBinding.qunit.js +1 -0
  884. package/test/sap/ui/core/qunit/resource/ResourceModel.qunit.js +5 -4
  885. package/test/sap/ui/core/qunit/routing/async/Target.qunit.js +20 -18
  886. package/test/sap/ui/core/qunit/routing/async/Targets.qunit.js +1 -4
  887. package/test/sap/ui/core/qunit/routing/fixture/routingConfig/Component.js +2 -25
  888. package/test/sap/ui/core/qunit/routing/fixture/routingConfig/manifest.json +28 -0
  889. package/test/sap/ui/core/qunit/rule/misc/silentEventBus.qunit.js +1 -2
  890. package/test/sap/ui/core/qunit/testdata/libraries/scenario11/lib1/library.js +11 -0
  891. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib1/library-preload.js +3 -1
  892. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib1/library.js +3 -1
  893. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib2/library-preload.js +3 -1
  894. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib2/library.js +3 -1
  895. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib3/library-preload.js +2 -1
  896. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib3/library.js +2 -1
  897. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib5/library-preload.js +2 -1
  898. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib5/library.js +2 -1
  899. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib6/library-preload.js +2 -1
  900. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib6/library.js +2 -1
  901. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib8/library-preload.js +2 -1
  902. package/test/sap/ui/core/qunit/testdata/libraries/scenario14/lib8/library.js +2 -1
  903. package/test/sap/ui/core/qunit/testdata/libraries/terminologies/integration/lib/library-preload.js +1 -1
  904. package/test/sap/ui/core/qunit/testdata/shortcutHints/Component.js +9 -0
  905. package/test/sap/ui/core/qunit/testdata/shortcutHints/RootView.controller.js +8 -0
  906. package/test/sap/ui/core/qunit/testdata/shortcutHints/RootView.view.xml +16 -0
  907. package/test/sap/ui/core/qunit/testdata/shortcutHints/lib/MyControl.js +27 -0
  908. package/test/sap/ui/core/qunit/testdata/shortcutHints/manifest.json +26 -0
  909. package/test/sap/ui/core/qunit/testdata/uilib-custom-theme-fallback/library.js +4 -5
  910. package/test/sap/ui/core/qunit/testdata/uilib-failing-css-import/library.js +5 -6
  911. package/test/sap/ui/core/qunit/testdata/xml-require/view/XMLTemplateProcessorAsync_require_expression.controller.js +2 -1
  912. package/test/sap/ui/core/qunit/testdata/xml-require/view/XMLTemplateProcessorAsync_require_expression.view.xml +18 -1
  913. package/test/sap/ui/core/qunit/testsuite.core.framework.qunit.js +3 -0
  914. package/test/sap/ui/core/qunit/testsuites/testsuite.control.framework.qunit.js +0 -4
  915. package/test/sap/ui/core/qunit/testsuites/testsuite.foundation.enablement.qunit.js +6 -1
  916. package/test/sap/ui/core/qunit/testsuites/testsuite.managed.object.qunit.js +4 -1
  917. package/test/sap/ui/core/qunit/testsuites/testsuite.modular.core.qunit.js +1 -1
  918. package/test/sap/ui/core/qunit/testsuites/testsuite.security.qunit.js +3 -9
  919. package/test/sap/ui/core/qunit/types/DataType.qunit.js +14 -3
  920. package/test/sap/ui/core/qunit/types/Date.qunit.js +3 -0
  921. package/test/sap/ui/core/qunit/types/DateFormat.qunit.js +391 -147
  922. package/test/sap/ui/core/qunit/types/DateFormatTimezones.qunit.js +32 -29
  923. package/test/sap/ui/core/qunit/types/DateInterval.qunit.js +7 -4
  924. package/test/sap/ui/core/qunit/types/FileSizeFormat.qunit.js +5 -1
  925. package/test/sap/ui/core/qunit/types/ListFormat.qunit.js +3 -0
  926. package/test/sap/ui/core/qunit/types/NumberFormat.qunit.js +4 -3
  927. package/test/sap/ui/core/qunit/types/NumberFormatCurrencies.qunit.js +5 -4
  928. package/test/sap/ui/core/qunit/types/NumberFormatCurrenciesTrailing.qunit.js +4 -3
  929. package/test/sap/ui/core/qunit/types/SimpleType.qunit.js +3 -0
  930. package/test/sap/ui/core/qunit/types/TimezoneUtil.qunit.js +23 -0
  931. package/test/sap/ui/core/qunit/types/Types.qunit.js +44 -10
  932. package/test/sap/ui/core/qunit/types/testsuite.types.qunit.js +3 -0
  933. package/test/sap/ui/core/qunit/util/InvisibleMessage.qunit.js +4 -4
  934. package/test/sap/ui/core/qunit/util/XMLPreprocessor.qunit.js +592 -83
  935. package/test/sap/ui/core/qunit/util/beforeBootstrap/jQuery.sap.FrameOptions-allowlist.js +7 -0
  936. package/test/sap/ui/core/qunit/util/beforeBootstrap/jQuery.sap.FrameOptions-frameOptions.js +7 -0
  937. package/test/sap/ui/core/qunit/{bootstrap/CfgFromGlobalObject.qunit.html → util/jQuery.sap.FrameOptions-meta-tag-override-mode.qunit.html} +7 -11
  938. package/test/sap/ui/core/qunit/util/jQuery.sap.FrameOptions-meta-tag-override-mode.qunit.js +3 -4
  939. package/test/sap/ui/core/qunit/util/jQuery.sap.FrameOptions-meta-tag-override-service.qunit.html +26 -0
  940. package/test/sap/ui/core/qunit/util/jQuery.sap.FrameOptions-meta-tag-override-service.qunit.js +3 -4
  941. package/test/sap/ui/core/qunit/{bootstrap/CfgDefaults.qunit.html → util/jQuery.sap.FrameOptions-meta-tag.qunit.html} +5 -8
  942. package/test/sap/ui/core/qunit/util/jQuery.sap.FrameOptions-meta-tag.qunit.js +3 -4
  943. package/test/sap/ui/core/qunit/util/jQuery.sap.Version.qunit.js +10 -10
  944. package/test/sap/ui/core/qunit/util/jquery.sap.logger.qunit.html +18 -0
  945. package/test/sap/ui/core/qunit/util/jquery.sap.resources.qunit.js +1 -1
  946. package/test/sap/ui/core/qunit/util/testsuite.util.qunit.js +1 -3
  947. package/test/sap/ui/core/qunit/xml/XMLListBinding.qunit.js +3 -0
  948. package/test/sap/ui/core/qunit/xml/XMLModel.qunit.js +3 -0
  949. package/test/sap/ui/core/qunit/xml/XMLPropertyBinding.qunit.js +3 -0
  950. package/test/sap/ui/core/qunit/xml/XMLTreeBinding.qunit.js +3 -0
  951. package/test/sap/ui/core/relnotes/changes-1.119.json +1 -12
  952. package/test/sap/ui/core/relnotes/changes-1.120.json +442 -0
  953. package/test/sap/ui/core/terminologies/App.controller.js +2 -3
  954. package/test/sap/ui/core/terminologies/main.js +2 -3
  955. package/test/sap/ui/test/qunit/TestUtils.qunit.js +3 -3
  956. package/src/sap/ui/core/ConfigTest.js +0 -17
  957. package/src/sap/ui/core/_ConfigurationProvider.js +0 -187
  958. package/test/sap/ui/core/ComponentExtensibility_CustomizingDisabled.html +0 -57
  959. package/test/sap/ui/core/qunit/bootstrap/CfgDefaults.qunit.js +0 -71
  960. package/test/sap/ui/core/qunit/bootstrap/CfgFromConfigAttribute.qunit.html +0 -29
  961. package/test/sap/ui/core/qunit/bootstrap/CfgFromConfigAttribute.qunit.js +0 -40
  962. package/test/sap/ui/core/qunit/bootstrap/CfgFromGlobalObject.beforeBootstrap.qunit.js +0 -20
  963. package/test/sap/ui/core/qunit/bootstrap/CfgFromGlobalObject.qunit.js +0 -40
  964. package/test/sap/ui/core/qunit/bootstrap/CfgFromTagAttributes.qunit.html +0 -42
  965. package/test/sap/ui/core/qunit/bootstrap/CfgFromTagAttributes.qunit.js +0 -49
  966. package/test/sap/ui/core/qunit/util/BusyIndicatorNoCore.qunit.js +0 -96
  967. package/test/sap/ui/core/qunit/util/beforeBootstrap/jQuery.sap.FrameOptions-meta-tag.js +0 -10
  968. package/test/sap/ui/core/samples/mvc/JSONView.html +0 -65
@@ -2044,7 +2044,7 @@ sap.ui.define([
2044
2044
  return mNewQueryOptions === mQueryOptions;
2045
2045
  }), true);
2046
2046
  this.mock(oGroupLevelCache).expects("read")
2047
- .withExactArgs(1, 1, 0, "~oGroupLock~", "~fnDataRequested~")
2047
+ .withExactArgs(1, 1, 0, "~oGroupLock~", "~fnDataRequested~", true)
2048
2048
  .returns(SyncPromise.resolve({value : aReadResult}));
2049
2049
  this.mock(oCache).expects("addElements")
2050
2050
  .withExactArgs(sinon.match.same(aReadResult), 2, sinon.match.same(oGroupLevelCache), 1);
@@ -2053,6 +2053,50 @@ sap.ui.define([
2053
2053
  return oCache.readGap(oGroupLevelCache, 2, 3, "~oGroupLock~", "~fnDataRequested~");
2054
2054
  });
2055
2055
 
2056
+ //*********************************************************************************************
2057
+ QUnit.test("readGap: created persisted", function (assert) {
2058
+ const oCache
2059
+ = _AggregationCache.create(this.oRequestor, "~", "", {}, {hierarchyQualifier : "X"});
2060
+ oCache.aElements = [,, "~oStartElement~"];
2061
+ oCache.aElements.$byPredicate = {};
2062
+ const oHelperMock = this.mock(_Helper);
2063
+ oHelperMock.expects("getPrivateAnnotation")
2064
+ .withExactArgs("~oStartElement~", "index").returns(undefined); // created
2065
+ oHelperMock.expects("getPrivateAnnotation")
2066
+ .withExactArgs("~oStartElement~", "predicate").returns("~sPredicate~");
2067
+ const oGroupLevelCache = {refreshSingle : mustBeMocked};
2068
+ this.mock(oGroupLevelCache).expects("refreshSingle")
2069
+ .withExactArgs("~oGroupLock~", "", -1, "~sPredicate~", true, false, "~fnDataRequested~")
2070
+ .returns(SyncPromise.resolve(Promise.resolve("~oElement~")));
2071
+ oHelperMock.expects("copyPrivateAnnotation")
2072
+ .withExactArgs("~oStartElement~", "context", "~oElement~");
2073
+ this.mock(oCache).expects("addElements")
2074
+ .withExactArgs("~oElement~", 2, sinon.match.same(oGroupLevelCache));
2075
+
2076
+ // code under test
2077
+ const oResult = oCache.readGap(oGroupLevelCache, 2, 3, "~oGroupLock~", "~fnDataRequested~");
2078
+
2079
+ assert.strictEqual(oCache.aElements.$byPredicate["~sPredicate~"], oResult);
2080
+
2081
+ return oResult.then(function (vResult) {
2082
+ assert.strictEqual(vResult, undefined, "without a defined result");
2083
+ });
2084
+ });
2085
+
2086
+ //*********************************************************************************************
2087
+ QUnit.test("readGap: multiple created persisted", function (assert) {
2088
+ const oCache
2089
+ = _AggregationCache.create(this.oRequestor, "~", "", {}, {hierarchyQualifier : "X"});
2090
+ oCache.aElements = [,, "~oStartElement~"];
2091
+ this.mock(_Helper).expects("getPrivateAnnotation")
2092
+ .withExactArgs("~oStartElement~", "index").returns(undefined); // created
2093
+
2094
+ assert.throws(function () {
2095
+ // code under test
2096
+ oCache.readGap(/*oGroupLevelCache*/null, 2, 4, "~oGroupLock~", "~fnDataRequested~");
2097
+ }, new Error("Not just a single created persisted"));
2098
+ });
2099
+
2056
2100
  //*********************************************************************************************
2057
2101
  [
2058
2102
  "read: expand before read has finished",
@@ -2074,7 +2118,7 @@ sap.ui.define([
2074
2118
  _AggregationHelper.createPlaceholder(1, 2, oGroupLevelCache)];
2075
2119
 
2076
2120
  this.mock(oGroupLevelCache).expects("read")
2077
- .withExactArgs(1, 2, 0, "~oGroupLock~", "~fnDataRequested~")
2121
+ .withExactArgs(1, 2, 0, "~oGroupLock~", "~fnDataRequested~", true)
2078
2122
  .callsFake(function () {
2079
2123
  // while the read request is running - simulate an expand
2080
2124
  oCache.aElements.splice(1, 0, {/*oInsertedNode*/});
@@ -2114,7 +2158,7 @@ sap.ui.define([
2114
2158
  _AggregationHelper.createPlaceholder(1, 2, oGroupLevelCache)];
2115
2159
 
2116
2160
  this.mock(oGroupLevelCache).expects("read")
2117
- .withExactArgs(1, 2, 0, "~oGroupLock~", "~fnDataRequested~")
2161
+ .withExactArgs(1, 2, 0, "~oGroupLock~", "~fnDataRequested~", true)
2118
2162
  .callsFake(function () {
2119
2163
  return SyncPromise.resolve().then(function () {
2120
2164
  // while the read request is running - simulate a collapse
@@ -2159,7 +2203,7 @@ sap.ui.define([
2159
2203
  _Helper.setPrivateAnnotation(oCache.aElements[5], "predicate", "('B')");
2160
2204
 
2161
2205
  this.mock(oGroupLevelCache).expects("read")
2162
- .withExactArgs(3, 3, 0, "~oGroupLock~", "~fnDataRequested~").returns(oPromise);
2206
+ .withExactArgs(3, 3, 0, "~oGroupLock~", "~fnDataRequested~", true).returns(oPromise);
2163
2207
  this.mock(oCache).expects("addElements")
2164
2208
  .withExactArgs(sinon.match.same(oReadResult.value), 3,
2165
2209
  sinon.match.same(oGroupLevelCache), 3);
@@ -2168,9 +2212,13 @@ sap.ui.define([
2168
2212
  oResult = oCache.readGap(oGroupLevelCache, 3, 6, "~oGroupLock~", "~fnDataRequested~");
2169
2213
 
2170
2214
  assert.deepEqual(oCache.aElements.$byPredicate, bAsync ? {
2171
- "('A')" : oPromise,
2172
- "('B')" : oPromise
2215
+ "('A')" : SyncPromise.resolve(), // Note: not a strictEqual!
2216
+ "('B')" : SyncPromise.resolve()
2173
2217
  } : {});
2218
+ if (bAsync) {
2219
+ assert.strictEqual(oCache.aElements.$byPredicate["('A')"], oResult);
2220
+ assert.strictEqual(oCache.aElements.$byPredicate["('B')"], oResult);
2221
+ }
2174
2222
 
2175
2223
  return oResult;
2176
2224
  });
@@ -2457,15 +2505,32 @@ sap.ui.define([
2457
2505
  oGroupNode = {
2458
2506
  "@$ui5._" : {
2459
2507
  cache : oGroupLevelCache,
2508
+ index : 42,
2460
2509
  groupLevelCount : 7,
2461
2510
  spliced : [{
2462
- "@$ui5._" : {predicate : "('A')"},
2511
+ "@$ui5._" : {
2512
+ index : 23,
2513
+ parent : oCache.oFirstLevel, // unrealistic!
2514
+ predicate : "('A')"
2515
+ },
2463
2516
  "@$ui5.node.level" : 10
2464
2517
  }, {
2465
- "@$ui5._" : {placeholder : true, predicate : "n/a"},
2518
+ "@$ui5._" : {index : 24, placeholder : true, predicate : "n/a"},
2466
2519
  "@$ui5.node.level" : 11
2467
2520
  }, {
2468
- "@$ui5._" : {expanding : true, predicate : "('C')"},
2521
+ "@$ui5._" : {
2522
+ index : 25,
2523
+ expanding : true,
2524
+ parent : oCache.oFirstLevel, // unrealistic!
2525
+ predicate : "('C')"
2526
+ },
2527
+ "@$ui5.node.level" : 12
2528
+ }, {
2529
+ "@$ui5._" : {
2530
+ parent : oCache.oFirstLevel, // unrealistic!
2531
+ predicate : "('created')",
2532
+ transientPredicate : "($uid=1-23)"
2533
+ },
2469
2534
  "@$ui5.node.level" : 12
2470
2535
  }]
2471
2536
  },
@@ -2477,13 +2542,14 @@ sap.ui.define([
2477
2542
  oUpdateAllExpectation;
2478
2543
 
2479
2544
  oGroupNode["@$ui5._"].spliced[200000] = {
2480
- "@$ui5._" : {predicate : "('D')"},
2545
+ "@$ui5._" : {index : 200023, predicate : "('D')"},
2481
2546
  "@$ui5.node.level" : 10
2482
2547
  };
2483
2548
  aSpliced = oGroupNode["@$ui5._"].spliced.slice();
2484
2549
  if (bStale) {
2485
2550
  oGroupNode["@$ui5._"].spliced.$stale = true;
2486
2551
  }
2552
+ oGroupNode["@$ui5._"].spliced.$index = 12;
2487
2553
  aElements = [{}, oGroupNode, {}, {}];
2488
2554
  oCache.aElements = aElements.slice();
2489
2555
  oCache.aElements.$byPredicate = {};
@@ -2507,6 +2573,8 @@ sap.ui.define([
2507
2573
  .withExactArgs(sinon.match.same(aSpliced[0]), "('A')");
2508
2574
  oCacheMock.expects("turnIntoPlaceholder")
2509
2575
  .withExactArgs(sinon.match.same(aSpliced[2]), "('C')");
2576
+ oCacheMock.expects("turnIntoPlaceholder")
2577
+ .withExactArgs(sinon.match.same(aSpliced[3]), "('created')");
2510
2578
  oCacheMock.expects("turnIntoPlaceholder")
2511
2579
  .withExactArgs(sinon.match.same(aSpliced[200000]), "('D')");
2512
2580
  } else {
@@ -2527,17 +2595,23 @@ sap.ui.define([
2527
2595
 
2528
2596
  // check expanded nodes
2529
2597
  assert.deepEqual(Object.keys(oCache.aElements),
2530
- ["0", "1", "2", "3", "4", "200002", "200003", "200004", "$byPredicate", "$count"]);
2598
+ ["0", "1", "2", "3", "4", "5", "200002", "200003", "200004", "$byPredicate",
2599
+ "$count"]);
2531
2600
  assert.strictEqual(oCache.aElements[2], aSpliced[0]);
2532
2601
  assert.strictEqual(aSpliced[0]["@$ui5.node.level"], 6);
2602
+ assert.strictEqual(aSpliced[0]["@$ui5._"].index, 53);
2533
2603
  assert.strictEqual(oCache.aElements[3], aSpliced[1]);
2534
2604
  assert.strictEqual(aSpliced[1]["@$ui5.node.level"], 7);
2605
+ assert.strictEqual(aSpliced[1]["@$ui5._"].index, 24);
2535
2606
  assert.strictEqual(oCache.aElements[4], aSpliced[2]);
2536
2607
  assert.strictEqual(aSpliced[2]["@$ui5.node.level"], 8);
2608
+ assert.strictEqual(aSpliced[2]["@$ui5._"].index, 55);
2537
2609
  assert.strictEqual(_Helper.hasPrivateAnnotation(aSpliced[2], "expanding"), bStale,
2538
2610
  "deleted only if not stale");
2611
+ assert.notOk("index" in aSpliced[3]["@$ui5._"]);
2539
2612
  assert.strictEqual(oCache.aElements[200002], aSpliced[200000]);
2540
2613
  assert.strictEqual(aSpliced[200000]["@$ui5.node.level"], 6);
2614
+ assert.strictEqual(aSpliced[200000]["@$ui5._"].index, 200023);
2541
2615
 
2542
2616
  // check moved nodes
2543
2617
  assert.strictEqual(oCache.aElements[200003], aElements[2]);
@@ -2546,6 +2620,8 @@ sap.ui.define([
2546
2620
  assert.deepEqual(oCache.aElements.$byPredicate, bStale ? {} : {
2547
2621
  "('A')" : aSpliced[0],
2548
2622
  "('C')" : aSpliced[2],
2623
+ "('created')" : aSpliced[3],
2624
+ "($uid=1-23)" : aSpliced[3],
2549
2625
  "('D')" : aSpliced[200000]
2550
2626
  });
2551
2627
  });
@@ -2711,28 +2787,13 @@ sap.ui.define([
2711
2787
  //*********************************************************************************************
2712
2788
  [false, true].forEach(function (bUntilEnd) { // whether the collapsed children span until the end
2713
2789
  [undefined, false, true].forEach(function (bSubtotalsAtBottomOnly) {
2714
- [undefined, 5, 6].forEach(function (iExpandTo) {
2715
- var bSubtotalsAtBottom = bSubtotalsAtBottomOnly !== undefined,
2716
- sTitle = "collapse: until end = " + bUntilEnd
2717
- + ", subtotalsAtBottomOnly = " + bSubtotalsAtBottomOnly
2718
- + ", expandTo = " + iExpandTo;
2719
-
2720
- if (bSubtotalsAtBottom && iExpandTo) {
2721
- return;
2722
- }
2723
- if (!bUntilEnd && iExpandTo > 5) {
2724
- return; // w/ iExpandTo === 6, the collapsed children span until the end
2725
- }
2790
+ var bSubtotalsAtBottom = bSubtotalsAtBottomOnly !== undefined,
2791
+ sTitle = "collapse: until end = " + bUntilEnd
2792
+ + ", subtotalsAtBottomOnly = " + bSubtotalsAtBottomOnly;
2726
2793
 
2727
2794
  QUnit.test(sTitle, function (assert) {
2728
- var oAggregation = iExpandTo
2729
- ? {
2730
- expandTo : iExpandTo,
2795
+ var oAggregation = {
2731
2796
  hierarchyQualifier : "X"
2732
- } : { // filled before by buildApply
2733
- aggregate : {},
2734
- group : {},
2735
- groupLevels : ["group"]
2736
2797
  },
2737
2798
  oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation),
2738
2799
  bCollapseBottom = bUntilEnd || bSubtotalsAtBottom, // whether bottom line is affected
@@ -2740,46 +2801,35 @@ sap.ui.define([
2740
2801
  "@$ui5.node.isExpanded" : false,
2741
2802
  A : "10" // placeholder for an aggregate with subtotals
2742
2803
  },
2743
- // eslint-disable-next-line no-nested-ternary
2744
- iDescendants = iExpandTo ? (iExpandTo > 5 ? 3 : 1) : undefined,
2745
2804
  aElements = [{
2746
2805
  // "@$ui5._" : {predicate : "('0')"},
2747
- // "@$ui5.node.level" : ignored
2748
2806
  }, {
2749
2807
  "@$ui5._" : {
2750
2808
  collapsed : oCollapsed,
2751
- descendants : iDescendants,
2809
+ index : "~index~",
2752
2810
  predicate : "('1')"
2753
- },
2754
- "@$ui5.node.isExpanded" : true,
2755
- "@$ui5.node.level" : 5
2811
+ }
2756
2812
  }, {
2757
- "@$ui5._" : {predicate : "('2')", transientPredicate : "($uid=1-23)"},
2758
- "@$ui5.node.level" : 6 // child
2813
+ "@$ui5._" : {predicate : "('2')", transientPredicate : "($uid=1-23)"}
2759
2814
  }, {
2760
- "@$ui5._" : {predicate : "('3')"},
2761
- "@$ui5.node.level" : iExpandTo ? 1 : 7 // placeholder for descendant, or grandchild
2815
+ "@$ui5._" : {predicate : "('3')"}
2762
2816
  }, {
2763
- "@$ui5._" : {predicate : "('4')"},
2817
+ "@$ui5._" : {predicate : "('4')"}
2764
2818
  // Note: for bSubtotalsAtBottom, this represents the extra row for subtotals
2765
- "@$ui5.node.level" : bUntilEnd ? 6 : 5 // child or sibling (or "uncle" etc.)
2766
2819
  }],
2767
2820
  aExpectedElements = [{
2768
2821
  // "@$ui5._" : {predicate : "('0')"},
2769
- // "@$ui5.node.level" : ignored
2770
2822
  }, {
2771
2823
  "@$ui5._" : {
2772
2824
  collapsed : oCollapsed,
2773
- descendants : iDescendants,
2825
+ index : "~index~",
2774
2826
  predicate : "('1')",
2775
2827
  spliced : [aElements[2], aElements[3], aElements[4]]
2776
2828
  },
2777
2829
  "@$ui5.node.isExpanded" : false,
2778
- "@$ui5.node.level" : 5,
2779
2830
  A : "10" // placeholder for an aggregate with subtotals
2780
2831
  }, {
2781
- "@$ui5._" : {predicate : "('4')"},
2782
- "@$ui5.node.level" : 5 // sibling
2832
+ "@$ui5._" : {predicate : "('4')"}
2783
2833
  }];
2784
2834
 
2785
2835
  if (bSubtotalsAtBottom) {
@@ -2805,6 +2855,8 @@ sap.ui.define([
2805
2855
  .withExactArgs(sinon.match.same(oCache.mChangeListeners), "~path~",
2806
2856
  sinon.match.same(aElements[1]), sinon.match.same(oCollapsed))
2807
2857
  .callThrough();
2858
+ this.mock(oCache).expects("countDescendants")
2859
+ .withExactArgs(sinon.match.same(aElements[1]), 1).returns(bUntilEnd ? 3 : 2);
2808
2860
 
2809
2861
  // code under test
2810
2862
  assert.strictEqual(oCache.collapse("~path~"), bCollapseBottom ? 3 : 2,
@@ -2829,188 +2881,97 @@ sap.ui.define([
2829
2881
  "('1')" : aElements[1],
2830
2882
  "('4')" : aElements[4]
2831
2883
  });
2884
+ assert.strictEqual(aElements[1]["@$ui5._"].spliced.$index, "~index~");
2832
2885
  });
2833
- });
2834
2886
  });
2835
2887
  });
2836
2888
 
2837
2889
  //*********************************************************************************************
2838
- QUnit.test("collapse: at end", function (assert) {
2839
- var oAggregation = { // filled before by buildApply
2840
- aggregate : {},
2841
- group : {},
2842
- groupLevels : ["group"]
2843
- },
2844
- oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation),
2845
- oCollapsed = {"@$ui5.node.isExpanded" : false},
2846
- aElements = [{
2847
- "@$ui5.node.groupLevelCount" : 42,
2848
- "@$ui5.node.isExpanded" : true,
2849
- "@$ui5.node.level" : 5
2850
- }];
2851
-
2852
- oCache.aElements = aElements.slice(); // simulate a read
2853
- this.mock(oCache).expects("getValue").withExactArgs("~path~").returns(aElements[0]);
2854
- this.mock(_AggregationHelper).expects("getCollapsedObject")
2855
- .withExactArgs(sinon.match.same(aElements[0])).returns(oCollapsed);
2856
- this.mock(_Helper).expects("getPrivateAnnotation")
2857
- .withExactArgs(sinon.match.same(aElements[0]), "descendants").returns(undefined);
2858
- this.mock(_Helper).expects("updateAll")
2859
- .withExactArgs(sinon.match.same(oCache.mChangeListeners), "~path~",
2860
- sinon.match.same(aElements[0]), sinon.match.same(oCollapsed))
2861
- .callThrough();
2862
-
2863
- // code under test
2864
- assert.strictEqual(oCache.collapse("~path~"), 0, "number of removed elements");
2865
-
2866
- assert.deepEqual(oCache.aElements, [{
2867
- "@$ui5._" : {
2868
- spliced : []
2869
- },
2870
- "@$ui5.node.groupLevelCount" : 42,
2871
- "@$ui5.node.isExpanded" : false,
2890
+ QUnit.test("countDescendants: until end", function (assert) {
2891
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
2892
+ hierarchyQualifier : "X"
2893
+ });
2894
+ // Note: the collapsed children span until the end
2895
+ oCache.aElements = [{
2896
+ // "@$ui5.node.level" : ignored
2897
+ }, {
2898
+ "@$ui5.node.isExpanded" : true,
2872
2899
  "@$ui5.node.level" : 5
2873
- }]);
2874
- assert.strictEqual(oCache.aElements[0], aElements[0]);
2875
- });
2876
-
2877
- //*********************************************************************************************
2878
- [false, true].forEach(function (bExpanded) {
2879
- var sTitle = "collapse: skip descendants of manually collapsed node; isExpanded=" + bExpanded;
2880
-
2881
- QUnit.test(sTitle, function (assert) {
2882
- var oAggregation = {
2883
- expandTo : 3,
2884
- hierarchyQualifier : "X"
2885
- },
2886
- oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation),
2887
- aElements = [{
2888
- "@$ui5._" : {
2889
- descendants : 41,
2890
- predicate : "('0')"
2891
- },
2892
- "@$ui5.node.isExpanded" : true,
2893
- "@$ui5.node.level" : 1
2894
- }, {
2895
- "@$ui5._" : {
2896
- descendants : 40,
2897
- predicate : "('1')"
2898
- },
2899
- "@$ui5.node.isExpanded" : bExpanded,
2900
- "@$ui5.node.level" : 2
2901
- }, {
2902
- "@$ui5._" : {
2903
- predicate : "('2')"
2904
- },
2905
- "@$ui5.node.level" : 1
2906
- }],
2907
- oPlaceholder,
2908
- aSpliced = [aElements[1]],
2909
- i;
2910
-
2911
- oCache.aElements = aElements.slice(); // simulate a read
2912
- oCache.aElements.$byPredicate = {
2913
- "('0')" : aElements[0],
2914
- "('1')" : aElements[1],
2915
- "('2')" : aElements[2]
2916
- };
2917
- if (bExpanded) {
2918
- for (i = 0; i < 40; i += 1) { // add 40 placeholders for descendants of ('1')
2919
- oPlaceholder = {"@$ui5.node.level" : 3};
2920
- oCache.aElements.splice(2, 0, oPlaceholder);
2921
- aSpliced.push(oPlaceholder);
2922
- }
2923
- }
2924
- this.mock(oCache).expects("getValue").withExactArgs("~path~").returns(aElements[0]);
2925
- // don't care about getCollapsedObject and updateAll here
2900
+ }, {
2901
+ "@$ui5.node.level" : 6 // child
2902
+ }, {
2903
+ "@$ui5.node.level" : 7 // grandchild
2904
+ }, {
2905
+ "@$ui5.node.level" : 6 // child
2906
+ }]; // simulate a read
2926
2907
 
2927
2908
  // code under test
2928
- assert.strictEqual(oCache.collapse("~path~"), bExpanded ? 41 : 1,
2909
+ assert.strictEqual(oCache.countDescendants(oCache.aElements[1], 1), 3,
2929
2910
  "number of removed elements");
2911
+ });
2930
2912
 
2931
- assert.deepEqual(oCache.aElements, [{
2913
+ //*********************************************************************************************
2914
+ QUnit.test("countDescendants: skip descendants of manually collapsed node", function (assert) {
2915
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
2916
+ expandTo : 3,
2917
+ hierarchyQualifier : "X"
2918
+ });
2919
+ oCache.aElements = [{
2932
2920
  "@$ui5._" : {
2933
2921
  descendants : 41,
2934
- predicate : "('0')",
2935
- spliced : aSpliced
2922
+ predicate : "('0')"
2936
2923
  },
2937
- "@$ui5.node.isExpanded" : false,
2924
+ "@$ui5.node.isExpanded" : true,
2938
2925
  "@$ui5.node.level" : 1
2926
+ }, {
2927
+ "@$ui5._" : {
2928
+ descendants : 40,
2929
+ predicate : "('1')"
2930
+ },
2931
+ "@$ui5.node.isExpanded" : true,
2932
+ "@$ui5.node.level" : 2
2939
2933
  }, {
2940
2934
  "@$ui5._" : {
2941
2935
  predicate : "('2')"
2942
2936
  },
2943
2937
  "@$ui5.node.level" : 1
2944
- }]);
2945
- assert.strictEqual(oCache.aElements[0], aElements[0]);
2946
- assert.strictEqual(oCache.aElements[1], aElements[2]);
2947
- });
2948
- });
2949
-
2950
- //*********************************************************************************************
2951
- QUnit.test("collapse: no descendants at edge of top pyramid", function (assert) {
2952
- var oAggregation = {
2953
- expandTo : 2,
2954
- hierarchyQualifier : "X"
2955
- },
2956
- oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation),
2957
- aElements = [{
2958
- "@$ui5._" : {
2959
- descendants : 2,
2960
- predicate : "('0')"
2961
- },
2962
- "@$ui5.node.isExpanded" : true,
2963
- "@$ui5.node.level" : 1
2964
- }, {
2965
- "@$ui5._" : {
2966
- // no descendants at edge of top pyramid!
2967
- predicate : "('1')"
2968
- },
2969
- "@$ui5.node.isExpanded" : false,
2970
- "@$ui5.node.level" : 2
2971
- }, {
2972
- "@$ui5._" : {
2973
- // no descendants at edge of top pyramid!
2974
- predicate : "('2')"
2975
- },
2976
- "@$ui5.node.isExpanded" : false,
2977
- "@$ui5.node.level" : 2
2978
- }, {
2979
- "@$ui5._" : {
2980
- predicate : "('3')"
2981
- },
2982
- "@$ui5.node.level" : 1
2983
- }];
2984
-
2985
- oCache.aElements = aElements.slice(); // simulate a read
2986
- oCache.aElements.$byPredicate = {
2987
- "('0')" : aElements[0],
2988
- "('1')" : aElements[1],
2989
- "('2')" : aElements[2],
2990
- "('3')" : aElements[3]
2991
- };
2992
- this.mock(oCache).expects("getValue").withExactArgs("~path~").returns(aElements[0]);
2993
- // don't care about getCollapsedObject and updateAll here
2938
+ }]; // simulate a read
2939
+ for (let i = 0; i < 40; i += 1) { // add 40 placeholders for descendants of ('1')
2940
+ oCache.aElements.splice(2, 0, {"@$ui5.node.level" : 3});
2941
+ }
2994
2942
 
2995
2943
  // code under test
2996
- assert.strictEqual(oCache.collapse("~path~"), 2, "number of removed elements");
2944
+ assert.strictEqual(oCache.countDescendants(oCache.aElements[0], 0), 41,
2945
+ "number of removed elements");
2946
+ });
2997
2947
 
2998
- assert.deepEqual(oCache.aElements, [{
2948
+ //*********************************************************************************************
2949
+ QUnit.test("countDescendants: no descendants at edge of top pyramid", function (assert) {
2950
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
2951
+ expandTo : 2,
2952
+ hierarchyQualifier : "X"
2953
+ });
2954
+ oCache.aElements = [{
2999
2955
  "@$ui5._" : {
3000
- descendants : 2,
3001
- predicate : "('0')",
3002
- spliced : [aElements[1], aElements[2]]
2956
+ descendants : 2
3003
2957
  },
3004
- "@$ui5.node.isExpanded" : false,
2958
+ "@$ui5.node.isExpanded" : true,
3005
2959
  "@$ui5.node.level" : 1
3006
2960
  }, {
3007
- "@$ui5._" : {
3008
- predicate : "('3')"
3009
- },
2961
+ // no descendants at edge of top pyramid!
2962
+ "@$ui5.node.isExpanded" : false,
2963
+ "@$ui5.node.level" : 2
2964
+ }, {
2965
+ // no descendants at edge of top pyramid!
2966
+ "@$ui5.node.isExpanded" : false,
2967
+ "@$ui5.node.level" : 2
2968
+ }, {
3010
2969
  "@$ui5.node.level" : 1
3011
- }]);
3012
- assert.strictEqual(oCache.aElements[0], aElements[0]);
3013
- assert.strictEqual(oCache.aElements[1], aElements[3]);
2970
+ }]; // simulate a read
2971
+
2972
+ // code under test
2973
+ assert.strictEqual(oCache.countDescendants(oCache.aElements[0], 0), 2,
2974
+ "number of removed elements");
3014
2975
  });
3015
2976
 
3016
2977
  //*********************************************************************************************
@@ -3022,21 +2983,28 @@ sap.ui.define([
3022
2983
  $NodeProperty : "SomeNodeID" // unrealistic mix, but never mind
3023
2984
  },
3024
2985
  oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation),
3025
- oPlaceholder = _AggregationHelper.createPlaceholder(NaN, 42, "~parent~"),
3026
- aElements = [{}, {}, oPlaceholder,, {}, {}],
2986
+ oPlaceholder42 = _AggregationHelper.createPlaceholder(NaN, 42, "~parent~"),
2987
+ oPlaceholder45 = _AggregationHelper.createPlaceholder(NaN, 45, "~parent~"),
2988
+ aElements = [{}, {}, oPlaceholder42,,, oPlaceholder45, {}, {}],
3027
2989
  aReadElements = [
3028
2990
  {"@$ui5._" : {predicate : "(1)"}},
3029
- {"@$ui5._" : {predicate : "(2)"}},
3030
- aElements[4]
2991
+ {"@$ui5._" : {predicate : "(2)", transientPredicate : "$uid=id-1-23"}},
2992
+ {"@$ui5._" : {predicate : "(3)"}},
2993
+ {"@$ui5._" : {predicate : "(4)"}},
2994
+ aElements[6]
3031
2995
  ];
3032
2996
 
3033
2997
  oCache.aElements = aElements.slice();
3034
2998
  oCache.aElements.$byPredicate = {
3035
2999
  "(2)" : SyncPromise.resolve() // SyncPromise may safely be overwritten
3036
3000
  };
3037
- this.mock(_AggregationHelper).expects("beforeOverwritePlaceholder")
3038
- .withExactArgs(sinon.match.same(oPlaceholder), sinon.match.same(aReadElements[0]),
3001
+ const oAggregationHelperMock = this.mock(_AggregationHelper);
3002
+ oAggregationHelperMock.expects("beforeOverwritePlaceholder")
3003
+ .withExactArgs(sinon.match.same(oPlaceholder42), sinon.match.same(aReadElements[0]),
3039
3004
  "~parent~", 42, "SomeNodeID");
3005
+ oAggregationHelperMock.expects("beforeOverwritePlaceholder")
3006
+ .withExactArgs(sinon.match.same(oPlaceholder45), sinon.match.same(aReadElements[3]),
3007
+ "~parent~", 44, "SomeNodeID");
3040
3008
  this.mock(_Helper).expects("updateNonExisting").never();
3041
3009
  this.mock(oCache).expects("hasPendingChangesForPath").never();
3042
3010
 
@@ -3047,18 +3015,67 @@ sap.ui.define([
3047
3015
  assert.strictEqual(oCache.aElements[1], aElements[1]);
3048
3016
  assert.strictEqual(oCache.aElements[2], aReadElements[0]);
3049
3017
  assert.strictEqual(oCache.aElements[3], aReadElements[1]);
3050
- assert.strictEqual(oCache.aElements[4], aElements[4]);
3051
- assert.strictEqual(oCache.aElements[5], aElements[5]);
3018
+ assert.strictEqual(oCache.aElements[4], aReadElements[2]);
3019
+ assert.strictEqual(oCache.aElements[5], aReadElements[3]);
3020
+ assert.strictEqual(oCache.aElements[6], aElements[6]);
3021
+ assert.strictEqual(oCache.aElements[7], aElements[7]);
3052
3022
  assert.deepEqual(oCache.aElements.$byPredicate, {
3053
3023
  "(1)" : aReadElements[0],
3054
- "(2)" : aReadElements[1]
3024
+ "(2)" : aReadElements[1],
3025
+ "$uid=id-1-23" : aReadElements[1],
3026
+ "(3)" : aReadElements[2],
3027
+ "(4)" : aReadElements[3]
3055
3028
  });
3056
3029
  assert.deepEqual(oCache.aElements, [
3057
3030
  {},
3058
3031
  {},
3059
3032
  {"@$ui5._" : {index : 42, parent : "~parent~", predicate : "(1)"}},
3060
- {"@$ui5._" : {index : 43, parent : "~parent~", predicate : "(2)"}},
3033
+ {"@$ui5._" // no index!
3034
+ : {parent : "~parent~", predicate : "(2)", transientPredicate : "$uid=id-1-23"}},
3035
+ {"@$ui5._" : {index : 43, parent : "~parent~", predicate : "(3)"}},
3036
+ {"@$ui5._" : {index : 44, parent : "~parent~", predicate : "(4)"}},
3037
+ {},
3038
+ {}
3039
+ ]);
3040
+ });
3041
+
3042
+ //*********************************************************************************************
3043
+ QUnit.test("addElements: no index for single created element", function (assert) {
3044
+ var oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
3045
+ hierarchyQualifier : "X",
3046
+ $NodeProperty : "SomeNodeID"
3047
+ }),
3048
+ oPlaceholder42 = _AggregationHelper.createPlaceholder(NaN, 42, "~parent~"),
3049
+ aElements = [{}, {}, oPlaceholder42, {}],
3050
+ oReadElement = {"@$ui5._" : {predicate : "(2)", transientPredicate : "$uid=id-1-23"}};
3051
+
3052
+ oCache.aElements = aElements.slice();
3053
+ oCache.aElements.$byPredicate = {
3054
+ "(2)" : SyncPromise.resolve() // SyncPromise may safely be overwritten
3055
+ };
3056
+ const oAggregationHelperMock = this.mock(_AggregationHelper);
3057
+ oAggregationHelperMock.expects("beforeOverwritePlaceholder")
3058
+ .withExactArgs(sinon.match.same(oPlaceholder42), sinon.match.same(oReadElement),
3059
+ "~parent~", undefined, "SomeNodeID");
3060
+ this.mock(_Helper).expects("updateNonExisting").never();
3061
+ this.mock(oCache).expects("hasPendingChangesForPath").never();
3062
+
3063
+ // code under test
3064
+ oCache.addElements(oReadElement, 2, "~parent~");
3065
+
3066
+ assert.strictEqual(oCache.aElements[0], aElements[0]);
3067
+ assert.strictEqual(oCache.aElements[1], aElements[1]);
3068
+ assert.strictEqual(oCache.aElements[2], oReadElement);
3069
+ assert.strictEqual(oCache.aElements[3], aElements[3]);
3070
+ assert.deepEqual(oCache.aElements.$byPredicate, {
3071
+ "(2)" : oReadElement,
3072
+ "$uid=id-1-23" : oReadElement
3073
+ });
3074
+ assert.deepEqual(oCache.aElements, [
3061
3075
  {},
3076
+ {},
3077
+ {"@$ui5._" // no index!
3078
+ : {parent : "~parent~", predicate : "(2)", transientPredicate : "$uid=id-1-23"}},
3062
3079
  {}
3063
3080
  ]);
3064
3081
  });
@@ -3086,7 +3103,6 @@ sap.ui.define([
3086
3103
  this.mock(_AggregationHelper).expects("beforeOverwritePlaceholder")
3087
3104
  .withExactArgs(sinon.match.same(oPlaceholder), sinon.match.same(oReadElement),
3088
3105
  sinon.match.same(oGroupLevelCache), 42, undefined);
3089
- this.mock(_Helper).expects("setPrivateAnnotation").exactly(bWithParentCache ? 2 : 0);
3090
3106
  this.mock(_Helper).expects("updateNonExisting").never();
3091
3107
  this.mock(oCache).expects("hasPendingChangesForPath").never();
3092
3108
 
@@ -3097,6 +3113,11 @@ sap.ui.define([
3097
3113
  assert.strictEqual(oCache.aElements[1], oReadElement);
3098
3114
  assert.strictEqual(oCache.aElements[2], aElements[2]);
3099
3115
  assert.deepEqual(oCache.aElements.$byPredicate, {"(1)" : oReadElement});
3116
+ assert.deepEqual(oReadElement, {
3117
+ "@$ui5._" : bWithParentCache
3118
+ ? {index : 42, parent : oGroupLevelCache, predicate : "(1)"}
3119
+ : {index : 42, predicate : "(1)"}
3120
+ });
3100
3121
  });
3101
3122
  });
3102
3123
 
@@ -3239,7 +3260,7 @@ sap.ui.define([
3239
3260
  },
3240
3261
  oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, oAggregation),
3241
3262
  aElements = [{},, {}],
3242
- oElement = {"@$ui5._" : {transientPredicate : "$uid=id-1-23"}};
3263
+ oElement = {"@$ui5._" : {predicate : "(1)", transientPredicate : "$uid=id-1-23"}};
3243
3264
 
3244
3265
  oCache.aElements = aElements.slice();
3245
3266
  oCache.aElements.$byPredicate = {};
@@ -3254,11 +3275,16 @@ sap.ui.define([
3254
3275
  assert.strictEqual(oCache.aElements[1], oElement);
3255
3276
  assert.strictEqual(oCache.aElements[2], aElements[2]);
3256
3277
  assert.deepEqual(oCache.aElements.$byPredicate, {
3257
- "$uid=id-1-23" : oElement
3278
+ "$uid=id-1-23" : oElement,
3279
+ "(1)" : oElement
3258
3280
  });
3259
3281
  assert.deepEqual(oCache.aElements, [
3260
3282
  {},
3261
- {"@$ui5._" : {index : 42, parent : "~parent~", transientPredicate : "$uid=id-1-23"}},
3283
+ {"@$ui5._" : {
3284
+ parent : "~parent~",
3285
+ predicate : "(1)",
3286
+ transientPredicate : "$uid=id-1-23"
3287
+ }},
3262
3288
  {}
3263
3289
  ]);
3264
3290
  });
@@ -3280,6 +3306,53 @@ sap.ui.define([
3280
3306
  "~result~");
3281
3307
  });
3282
3308
 
3309
+ //*********************************************************************************************
3310
+ QUnit.test("getParentIndex", function (assert) {
3311
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {},
3312
+ {hierarchyQualifier : "X"});
3313
+
3314
+ oCache.aElements[0] = {
3315
+ "@$ui5.node.level" : 0
3316
+ };
3317
+ oCache.aElements[1] = {
3318
+ "@$ui5.node.level" : 1
3319
+ };
3320
+ oCache.aElements[2] = {
3321
+ "@$ui5.node.level" : 2
3322
+ };
3323
+ oCache.aElements[3] = {
3324
+ "@$ui5.node.level" : 3
3325
+ };
3326
+ oCache.aElements[4] = {
3327
+ "@$ui5.node.level" : 2
3328
+ };
3329
+
3330
+ //code under test
3331
+ assert.strictEqual(oCache.getParentIndex(0), -1);
3332
+ assert.strictEqual(oCache.getParentIndex(1), -1);
3333
+ assert.strictEqual(oCache.getParentIndex(2), 1);
3334
+ assert.strictEqual(oCache.getParentIndex(3), 2);
3335
+ assert.strictEqual(oCache.getParentIndex(4), 1);
3336
+ });
3337
+
3338
+ //*********************************************************************************************
3339
+ QUnit.test("getParentIndex: error state", function (assert) {
3340
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {},
3341
+ {hierarchyQualifier : "X"});
3342
+
3343
+ oCache.aElements[0] = {
3344
+ "@$ui5.node.level" : 3
3345
+ };
3346
+ oCache.aElements[1] = {
3347
+ "@$ui5.node.level" : 2
3348
+ };
3349
+
3350
+ assert.throws(function () {
3351
+ // code under test
3352
+ oCache.getParentIndex(1);
3353
+ }, new Error("Unexpected error"));
3354
+ });
3355
+
3283
3356
  //*********************************************************************************************
3284
3357
  [false, true].forEach(function (bCount) {
3285
3358
  [undefined, "~group~"].forEach(function (sGroupId) {
@@ -3625,6 +3698,7 @@ sap.ui.define([
3625
3698
  var oAggregation = {
3626
3699
  hierarchyQualifier : "X"
3627
3700
  },
3701
+ oAggregationHelperMock = this.mock(_AggregationHelper),
3628
3702
  oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation),
3629
3703
  oHelperMock = this.mock(_Helper),
3630
3704
  oParentCache = {
@@ -3638,23 +3712,39 @@ sap.ui.define([
3638
3712
  };
3639
3713
 
3640
3714
  oHelperMock.expects("hasPrivateAnnotation")
3641
- .withExactArgs("~oElement~", "placeholder").returns(false);
3642
- oHelperMock.expects("setPrivateAnnotation").withExactArgs("~oElement~", "placeholder", 1);
3643
- this.mock(_AggregationHelper).expects("markSplicedStale").withExactArgs("~oElement~");
3644
- oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElement~", "parent")
3645
- .returns(oParentCache);
3646
- oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElement~", "index")
3715
+ .withExactArgs("~oElementB~", "placeholder").returns(false);
3716
+ oHelperMock.expects("setPrivateAnnotation").withExactArgs("~oElementB~", "placeholder", 1);
3717
+ oAggregationHelperMock.expects("markSplicedStale").withExactArgs("~oElementB~");
3718
+ oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElementB~", "index")
3647
3719
  .returns(42);
3648
- this.mock(oParentCache).expects("drop").withExactArgs(42, "('B')");
3720
+ oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElementB~", "parent")
3721
+ .returns(oParentCache);
3722
+ this.mock(oParentCache).expects("drop").withExactArgs(42, "('B')", true);
3649
3723
 
3650
3724
  // code under test
3651
- oCache.turnIntoPlaceholder("~oElement~", "('B')");
3725
+ oCache.turnIntoPlaceholder("~oElementB~", "('B')");
3652
3726
 
3653
3727
  assert.deepEqual(oCache.aElements.$byPredicate, {
3654
3728
  "('A')" : "~a~",
3655
3729
  "('C')" : "~c~"
3656
3730
  });
3657
3731
 
3732
+ oHelperMock.expects("hasPrivateAnnotation")
3733
+ .withExactArgs("~oElementC~", "placeholder").returns(false);
3734
+ oHelperMock.expects("setPrivateAnnotation").withExactArgs("~oElementC~", "placeholder", 1);
3735
+ oAggregationHelperMock.expects("markSplicedStale").withExactArgs("~oElementC~");
3736
+ oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElementC~", "index")
3737
+ .returns(undefined); // simulate a created element
3738
+ oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElementC~", "parent").never();
3739
+ // no drop!
3740
+
3741
+ // code under test
3742
+ oCache.turnIntoPlaceholder("~oElementC~", "('C')");
3743
+
3744
+ assert.deepEqual(oCache.aElements.$byPredicate, {
3745
+ "('A')" : "~a~"
3746
+ });
3747
+
3658
3748
  oCache.aElements = null; // do not touch ;-)
3659
3749
  // no other method calls expected!
3660
3750
  oHelperMock.expects("hasPrivateAnnotation")
@@ -3664,6 +3754,64 @@ sap.ui.define([
3664
3754
  oCache.turnIntoPlaceholder("~oElement~", "n/a");
3665
3755
  });
3666
3756
 
3757
+ //*********************************************************************************************
3758
+ QUnit.test("isAncestorOf: simple cases", function (assert) {
3759
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
3760
+ hierarchyQualifier : "X"
3761
+ });
3762
+ this.mock(oCache).expects("countDescendants").never();
3763
+
3764
+ // code under test
3765
+ assert.strictEqual(oCache.isAncestorOf(23, 23), true);
3766
+
3767
+ // code under test
3768
+ assert.strictEqual(oCache.isAncestorOf(42, 23), false);
3769
+
3770
+ oCache.aElements[17] = {"@$ui5.node.isExpanded" : false};
3771
+
3772
+ // code under test
3773
+ assert.strictEqual(oCache.isAncestorOf(17, 18), false);
3774
+
3775
+ oCache.aElements[18] = {
3776
+ "@$ui5.node.isExpanded" : true,
3777
+ "@$ui5.node.level" : 3
3778
+ };
3779
+ oCache.aElements[19] = {
3780
+ "@$ui5.node.level" : 3 // same level
3781
+ };
3782
+
3783
+ // code under test
3784
+ assert.strictEqual(oCache.isAncestorOf(18, 19), false);
3785
+
3786
+ oCache.aElements[20] = {
3787
+ "@$ui5.node.level" : 2 // lower level
3788
+ };
3789
+
3790
+ // code under test
3791
+ assert.strictEqual(oCache.isAncestorOf(18, 20), false);
3792
+ });
3793
+
3794
+ //*********************************************************************************************
3795
+ [-1, 0, +1].forEach((iDelta, i) => {
3796
+ QUnit.test("isAncestorOf: countDescendants #" + i, function (assert) {
3797
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
3798
+ hierarchyQualifier : "X"
3799
+ });
3800
+ oCache.aElements[23] = {
3801
+ "@$ui5.node.isExpanded" : true,
3802
+ "@$ui5.node.level" : 3
3803
+ };
3804
+ oCache.aElements[42] = {
3805
+ "@$ui5.node.level" : 4
3806
+ };
3807
+ this.mock(oCache).expects("countDescendants")
3808
+ .withExactArgs(sinon.match.same(oCache.aElements[23]), 23).returns(42 - 23 + iDelta);
3809
+
3810
+ // code under test
3811
+ assert.strictEqual(oCache.isAncestorOf(23, 42), i > 0);
3812
+ });
3813
+ });
3814
+
3667
3815
  //*********************************************************************************************
3668
3816
  QUnit.test("keepOnlyGivenElements: empty", function (assert) {
3669
3817
  var oAggregation = {
@@ -3688,6 +3836,8 @@ sap.ui.define([
3688
3836
  "@$ui5._" : {predicate : "('B')"}
3689
3837
  }, {
3690
3838
  "@$ui5._" : {predicate : "('C')"}
3839
+ }, {
3840
+ "@$ui5._" : {transientPredicate : "($uid=1-23)"} // must be ignored
3691
3841
  }],
3692
3842
  aResult;
3693
3843
 
@@ -3710,132 +3860,173 @@ sap.ui.define([
3710
3860
  //*********************************************************************************************
3711
3861
  [false, true].forEach((bTransient) => {
3712
3862
  [0, 1].forEach((iOldSiblingCount) => {
3713
- [false, true].forEach((bParentHasCache) => {
3714
- const sTitle = `move: already transient = ${bTransient},
3715
- old sibling count = ${iOldSiblingCount}, new parent already has cache = ${bParentHasCache}`;
3863
+ [false, true].forEach((bParentIsLeaf) => {
3864
+ [false, true].forEach((bSpliced) => {
3865
+ const sTitle = `move: already transient = ${bTransient},
3866
+ old sibling count = ${iOldSiblingCount}, new parent is leaf = ${bParentIsLeaf},
3867
+ new parent was expanded before = ${bSpliced}`;
3716
3868
 
3717
- QUnit.test(sTitle, function (assert) {
3718
- const oCache = _AggregationCache.create(this.oRequestor, "n/a", "", {}, {
3869
+ if (bParentIsLeaf && bSpliced) {
3870
+ return;
3871
+ }
3872
+
3873
+ QUnit.test(sTitle, function (assert) {
3874
+ const oHelperMock = this.mock(_Helper);
3875
+ oHelperMock.expects("uid").withExactArgs().returns("1-23");
3876
+ const oCache = _AggregationCache.create(this.oRequestor, "n/a", "", {}, {
3719
3877
  $ParentNavigationProperty : "myParent",
3720
3878
  hierarchyQualifier : "X"
3721
3879
  });
3722
- const oOldParent = {"@$ui5.node.isExpanded" : "n/a"};
3723
- const oParentNode = {"@$ui5.node.level" : 9};
3724
- oCache.aElements = ["a", oOldParent, "~oChildNode~", "d", "e", "f", "g", oParentNode, "i"];
3880
+ oCache.iReadLength = "~iReadLength~";
3881
+ const oChildNode = {ID : "child"};
3882
+ const oParentNode = {"@$ui5.node.level" : 9, ID : "parent"};
3883
+ if (!bParentIsLeaf) {
3884
+ oParentNode["@$ui5.node.isExpanded"] = false;
3885
+ }
3886
+ oCache.aElements = ["a", "~oOldParent~", oChildNode, "d", "e", "f", "g", oParentNode, "i"];
3725
3887
  oCache.aElements.$byPredicate = {
3726
- "('23')" : "~oChildNode~",
3888
+ "('23')" : oChildNode,
3727
3889
  "('42')" : oParentNode
3728
3890
  };
3891
+ oCache.aElements.$count = 100;
3892
+ const oParentCache = {
3893
+ read : mustBeMocked,
3894
+ restoreElement : mustBeMocked,
3895
+ setEmpty : mustBeMocked
3896
+ };
3897
+ oHelperMock.expects("getPrivateAnnotation")
3898
+ .withExactArgs(sinon.match.same(oParentNode), "cache")
3899
+ .returns(bParentIsLeaf || !bSpliced ? undefined : oParentCache);
3900
+ this.mock(oCache).expects("createGroupLevelCache")
3901
+ .exactly(bParentIsLeaf || !bSpliced ? 1 : 0)
3902
+ .withExactArgs(sinon.match.same(oParentNode)).returns(oParentCache);
3903
+ const oGroupLock = {
3904
+ getUnlockedCopy : mustBeMocked
3905
+ };
3906
+ if (!bParentIsLeaf && !bSpliced) {
3907
+ this.mock(oParentCache).expects("restoreElement")
3908
+ .withExactArgs(undefined, 0, sinon.match.same(oChildNode), "", undefined,
3909
+ "($uid=1-23)");
3910
+ this.mock(oGroupLock).expects("getUnlockedCopy").withExactArgs()
3911
+ .returns("~unlockedCopy~");
3912
+ this.mock(oParentCache).expects("read")
3913
+ .withExactArgs(0, "~iReadLength~", 0, "~unlockedCopy~")
3914
+ .returns(SyncPromise.resolve());
3915
+ }
3729
3916
  const oRequestExpectation = this.mock(this.oRequestor).expects("request")
3730
- .withExactArgs("PATCH", "Foo('23')", "~oGroupLock~", {
3731
- "If-Match" : "~oChildNode~",
3917
+ .withExactArgs("PATCH", "Foo('23')", sinon.match.same(oGroupLock), {
3918
+ "If-Match" : oChildNode,
3732
3919
  Prefer : "return=minimal"
3733
3920
  }, {"myParent@odata.bind" : "Foo('42')"},
3734
3921
  /*fnSubmit*/null, /*fnCancel*/sinon.match.func)
3735
3922
  .resolves({"@odata.etag" : "etag"});
3736
- const oHelperMock = this.mock(_Helper);
3737
3923
  oHelperMock.expects("updateExisting")
3738
- .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('23')", "~oChildNode~",
3739
- {"@odata.etag" : "etag"});
3740
- const oCacheMock = this.mock(oCache);
3741
- oCacheMock.expects("shiftIndex").withExactArgs(2, -1).callsFake(function () {
3742
- assert.deepEqual(oCache.aElements,
3743
- ["a", oOldParent, "~oChildNode~", "d", "e", "f", "g", oParentNode, "i"]);
3744
- });
3924
+ .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('23')",
3925
+ sinon.match.same(oChildNode), {"@odata.etag" : "etag", "@$ui5.node.level" : 10});
3745
3926
  const oOldParentCache = {
3746
3927
  getValue : mustBeMocked,
3747
3928
  removeElement : mustBeMocked,
3748
3929
  setActive : mustBeMocked
3749
3930
  };
3750
- oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oChildNode~", "parent")
3751
- .returns(oOldParentCache);
3752
- oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oChildNode~", "index")
3753
- .returns("~index~");
3754
- this.mock(oOldParentCache).expects("removeElement")
3755
- .withExactArgs(undefined, "~index~", "('23')", "");
3931
+ oHelperMock.expects("getPrivateAnnotation")
3932
+ .withExactArgs(sinon.match.same(oChildNode), "parent").returns(oOldParentCache);
3933
+ oHelperMock.expects("getPrivateAnnotation")
3934
+ .withExactArgs(sinon.match.same(oChildNode), "index", 0).returns("~index~");
3935
+ this.mock(oOldParentCache).expects("removeElement").withExactArgs("~index~", "('23')");
3756
3936
  this.mock(oOldParentCache).expects("getValue").withExactArgs("$count")
3757
3937
  .returns(iOldSiblingCount);
3758
- oHelperMock.expects("getPrivateAnnotation").exactly(iOldSiblingCount ? 0 : 1)
3759
- .withExactArgs(sinon.match.same(oOldParent), "predicate").returns("('b')");
3760
- oHelperMock.expects("updateAll").exactly(iOldSiblingCount ? 0 : 1)
3761
- .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('b')",
3762
- sinon.match.same(oOldParent), {"@$ui5.node.isExpanded" : undefined});
3938
+ this.mock(oCache).expects("makeLeaf").exactly(iOldSiblingCount ? 0 : 1)
3939
+ .withExactArgs("~oOldParent~");
3763
3940
  oHelperMock.expects("deletePrivateAnnotation").exactly(iOldSiblingCount ? 0 : 1)
3764
- .withExactArgs(sinon.match.same(oOldParent), "cache");
3941
+ .withExactArgs("~oOldParent~", "cache");
3765
3942
  this.mock(oOldParentCache).expects("setActive").exactly(iOldSiblingCount ? 0 : 1)
3766
3943
  .withExactArgs(false);
3944
+ oHelperMock.expects("deletePrivateAnnotation")
3945
+ .withExactArgs(sinon.match.same(oChildNode), "index");
3767
3946
  oHelperMock.expects("hasPrivateAnnotation")
3768
- .withExactArgs("~oChildNode~", "transientPredicate").returns(bTransient);
3769
- oHelperMock.expects("uid").exactly(bTransient ? 0 : 1).withExactArgs().returns("1-23");
3947
+ .withExactArgs(sinon.match.same(oChildNode), "transientPredicate").returns(bTransient);
3770
3948
  oHelperMock.expects("setPrivateAnnotation").exactly(bTransient ? 0 : 1)
3771
- .withExactArgs("~oChildNode~", "transientPredicate", "($uid=1-23)");
3949
+ .withExactArgs(sinon.match.same(oChildNode), "transientPredicate", "($uid=1-23)");
3772
3950
  oHelperMock.expects("updateAll").exactly(bTransient ? 0 : 1)
3773
- .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('23')", "~oChildNode~",
3774
- {"@$ui5.context.isTransient" : false});
3775
- const oParentCache = {
3776
- restoreElement : mustBeMocked,
3777
- setEmpty : mustBeMocked
3778
- };
3779
- oHelperMock.expects("getPrivateAnnotation")
3780
- .withExactArgs(sinon.match.same(oParentNode), "cache")
3781
- .returns(bParentHasCache ? oParentCache : undefined);
3782
- oCacheMock.expects("createGroupLevelCache").exactly(bParentHasCache ? 0 : 1)
3783
- .withExactArgs(sinon.match.same(oParentNode)).returns(oParentCache);
3784
- this.mock(oParentCache).expects("setEmpty").exactly(bParentHasCache ? 0 : 1)
3951
+ .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('23')",
3952
+ sinon.match.same(oChildNode), {"@$ui5.context.isTransient" : false});
3953
+ this.mock(oCache).expects("shiftIndex").exactly(bTransient ? 0 : 1)
3954
+ .withExactArgs(2, -1).callsFake(function () {
3955
+ assert.deepEqual(oCache.aElements,
3956
+ ["a", "~oOldParent~", oChildNode, "d", "e", "f", "g", oParentNode, "i"]);
3957
+ });
3958
+ this.mock(oParentCache).expects("setEmpty").exactly(bParentIsLeaf ? 1 : 0)
3785
3959
  .withExactArgs();
3786
- oHelperMock.expects("setPrivateAnnotation").exactly(bParentHasCache ? 0 : 1)
3960
+ const oCacheExpectation = oHelperMock.expects("setPrivateAnnotation")
3961
+ .exactly(bParentIsLeaf || !bSpliced ? 1 : 0)
3787
3962
  .withExactArgs(sinon.match.same(oParentNode), "cache", sinon.match.same(oParentCache));
3788
- oHelperMock.expects("updateAll").exactly(bParentHasCache ? 0 : 1)
3963
+ oHelperMock.expects("updateAll").exactly(bParentIsLeaf ? 1 : 0)
3789
3964
  .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('42')",
3790
3965
  sinon.match.same(oParentNode), {"@$ui5.node.isExpanded" : true});
3791
- this.mock(oParentCache).expects("restoreElement")
3792
- .withExactArgs(undefined, 0, "~oChildNode~", "");
3793
- oHelperMock.expects("setPrivateAnnotation").withExactArgs("~oChildNode~", "index", 0);
3794
3966
  const oParentExpectation = oHelperMock.expects("setPrivateAnnotation")
3795
- .withExactArgs("~oChildNode~", "parent", sinon.match.same(oParentCache));
3796
- const oNodeLevelExpectation = oHelperMock.expects("updateAll")
3797
- .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('23')", "~oChildNode~",
3798
- {"@$ui5.node.level" : 10});
3799
- oCacheMock.expects("shiftIndex").withExactArgs(7, +1).callsFake(function () {
3800
- assert.deepEqual(oCache.aElements,
3801
- ["a", oOldParent, "d", "e", "f", "g", oParentNode, "~oChildNode~", "i"]);
3802
- // 'relies on "parent" & "@$ui5.node.level"!'
3803
- assert.strictEqual(oParentExpectation.callCount, 1);
3804
- assert.strictEqual(oNodeLevelExpectation.callCount, 1);
3967
+ .withExactArgs(sinon.match.same(oChildNode), "parent", sinon.match.same(oParentCache));
3968
+ if (bParentIsLeaf || bSpliced) {
3969
+ this.mock(oParentCache).expects("restoreElement")
3970
+ .withExactArgs(undefined, 0, sinon.match.same(oChildNode), "");
3971
+ }
3972
+ const aSpliced = bSpliced ? [{"@$ui5.node.level" : 7}, "X", "Y", "Z"] : undefined;
3973
+ oHelperMock.expects("getPrivateAnnotation").exactly(bParentIsLeaf || bSpliced ? 1 : 0)
3974
+ .withExactArgs(sinon.match.same(oParentNode), "spliced").returns(aSpliced);
3975
+ this.mock(oCache).expects("expand").exactly(!bParentIsLeaf ? 1 : 0)
3976
+ .withExactArgs(sinon.match.same(_GroupLock.$cached), "('42')")
3977
+ .callsFake(function () {
3978
+ if (bSpliced) {
3979
+ assert.strictEqual(oChildNode["@$ui5.node.level"], 7);
3980
+ assert.deepEqual(aSpliced,
3981
+ [oChildNode, {"@$ui5.node.level" : 7}, "X", "Y", "Z"]);
3982
+ } else {
3983
+ assert.deepEqual(oChildNode, {ID : "child"}, "unchanged");
3984
+ assert.ok(oCacheExpectation.calledOnce);
3985
+ }
3986
+ assert.strictEqual(oCache.aElements.$count, 99);
3987
+ assert.ok(oParentExpectation.calledOnce);
3988
+ return SyncPromise.resolve("~iResult~");
3805
3989
  });
3806
3990
 
3807
3991
  // code under test
3808
- return oCache.move("~oGroupLock~", "Foo('23')", "Foo('42')")
3809
- .then(function (vResult) {
3810
- assert.strictEqual(vResult, undefined, "without a defined result");
3811
- assert.deepEqual(oCache.aElements,
3812
- ["a", oOldParent, "d", "e", "f", "g", oParentNode, "~oChildNode~", "i"]);
3992
+ const oSyncPromise = oCache.move(oGroupLock, "Foo('23')", "Foo('42')");
3993
+
3994
+ assert.strictEqual(oSyncPromise.isPending(), true);
3995
+
3996
+ return oSyncPromise.then(function (iResult) {
3997
+ assert.strictEqual(iResult, !bParentIsLeaf ? "~iResult~" : 1);
3998
+ assert.deepEqual(oCache.aElements, bParentIsLeaf
3999
+ ? ["a", "~oOldParent~", "d", "e", "f", "g", oParentNode, oChildNode, "i"]
4000
+ : ["a", "~oOldParent~", "d", "e", "f", "g", oParentNode, "i"]);
3813
4001
  assert.deepEqual(oCache.aElements.$byPredicate, bTransient ? {
3814
- "('23')" : "~oChildNode~",
4002
+ "('23')" : oChildNode,
3815
4003
  "('42')" : oParentNode
3816
4004
  } : {
3817
- "($uid=1-23)" : "~oChildNode~",
3818
- "('23')" : "~oChildNode~",
4005
+ "($uid=1-23)" : oChildNode,
4006
+ "('23')" : oChildNode,
3819
4007
  "('42')" : oParentNode
3820
4008
  });
3821
- assert.deepEqual(oOldParent,
3822
- iOldSiblingCount ? {"@$ui5.node.isExpanded" : "n/a"} : {});
4009
+ assert.strictEqual(oCache.aElements.$count, !bParentIsLeaf ? 99 : 100);
3823
4010
 
3824
4011
  // code under test (invoke fnCancel which does nothing)
3825
4012
  oRequestExpectation.args[0][6]();
3826
4013
  });
3827
4014
  });
4015
+ });
3828
4016
  });
3829
4017
  });
3830
4018
  });
3831
4019
 
3832
4020
  //*********************************************************************************************
3833
- QUnit.test("move: failure", function (assert) {
4021
+ QUnit.test("move: PATCH failure", function (assert) {
3834
4022
  const oCache = _AggregationCache.create(this.oRequestor, "n/a", "", {}, {
3835
4023
  $ParentNavigationProperty : "myParent",
3836
4024
  hierarchyQualifier : "X"
3837
4025
  });
3838
4026
  oCache.aElements.$byPredicate["('23')"] = "~oChildNode~";
4027
+ oCache.aElements.$byPredicate["('42')"] = "~oParentNode~";
4028
+ this.mock(_Helper).expects("getPrivateAnnotation").withExactArgs("~oParentNode~", "cache")
4029
+ .returns("n/a");
3839
4030
  const oError = new Error("This call intentionally failed");
3840
4031
  this.mock(this.oRequestor).expects("request")
3841
4032
  .withExactArgs("PATCH", "Foo('23')", "~oGroupLock~", {
@@ -3846,8 +4037,59 @@ sap.ui.define([
3846
4037
  .rejects(oError);
3847
4038
 
3848
4039
  // code under test
3849
- return oCache.move("~oGroupLock~", "Foo('23')", "Foo('42')")
3850
- .then(function () {
4040
+ const oSyncPromise = oCache.move("~oGroupLock~", "Foo('23')", "Foo('42')");
4041
+
4042
+ assert.strictEqual(oSyncPromise.isPending(), true);
4043
+
4044
+ return oSyncPromise.then(function () {
4045
+ assert.ok(false, "unexpected success");
4046
+ }, function (oError0) {
4047
+ assert.strictEqual(oError0, oError);
4048
+ });
4049
+ });
4050
+
4051
+ //*********************************************************************************************
4052
+ QUnit.test("move: GET failure", function (assert) {
4053
+ const oCache = _AggregationCache.create(this.oRequestor, "n/a", "", {}, {
4054
+ $ParentNavigationProperty : "myParent",
4055
+ hierarchyQualifier : "X"
4056
+ });
4057
+ oCache.iReadLength = "~iReadLength~";
4058
+ oCache.aElements.$byPredicate["('23')"] = "~oChildNode~";
4059
+ const oParentNode = {"@$ui5.node.isExpanded" : false};
4060
+ oCache.aElements.$byPredicate["('42')"] = oParentNode;
4061
+ const oParentCache = {
4062
+ read : mustBeMocked,
4063
+ restoreElement : mustBeMocked,
4064
+ setEmpty : mustBeMocked
4065
+ };
4066
+ this.mock(oCache).expects("createGroupLevelCache")
4067
+ .withExactArgs(sinon.match.same(oParentNode)).returns(oParentCache);
4068
+ this.mock(_Helper).expects("uid").withExactArgs().returns("1-23");
4069
+ this.mock(oParentCache).expects("restoreElement")
4070
+ .withExactArgs(undefined, 0, "~oChildNode~", "", undefined, "($uid=1-23)");
4071
+ const oGroupLock = {
4072
+ getUnlockedCopy : mustBeMocked
4073
+ };
4074
+ this.mock(oGroupLock).expects("getUnlockedCopy").withExactArgs().returns("~unlockedCopy~");
4075
+ const oError = new Error("This call intentionally failed");
4076
+ this.mock(oParentCache).expects("read")
4077
+ .withExactArgs(0, "~iReadLength~", 0, "~unlockedCopy~")
4078
+ .returns(SyncPromise.resolve(Promise.reject(oError)));
4079
+ this.mock(this.oRequestor).expects("request")
4080
+ .withExactArgs("PATCH", "Foo('23')", sinon.match.same(oGroupLock), {
4081
+ "If-Match" : "~oChildNode~",
4082
+ Prefer : "return=minimal"
4083
+ }, {"myParent@odata.bind" : "Foo('42')"},
4084
+ /*fnSubmit*/null, /*fnCancel*/sinon.match.func)
4085
+ .resolves();
4086
+
4087
+ // code under test
4088
+ const oSyncPromise = oCache.move(oGroupLock, "Foo('23')", "Foo('42')");
4089
+
4090
+ assert.strictEqual(oSyncPromise.isPending(), true);
4091
+
4092
+ return oSyncPromise.then(function () {
3851
4093
  assert.ok(false, "unexpected success");
3852
4094
  }, function (oError0) {
3853
4095
  assert.strictEqual(oError0, oError);
@@ -3856,11 +4098,20 @@ sap.ui.define([
3856
4098
 
3857
4099
  //*********************************************************************************************
3858
4100
  [false, true].forEach(function (bHasGroupLevelCache) {
3859
- QUnit.test("create: already has group level cache: " + bHasGroupLevelCache, function (assert) {
4101
+ [false, true].forEach(function (bInFirstLevel) {
4102
+ var sTitle = "create: already has group level cache: " + bHasGroupLevelCache
4103
+ + ", create inside oFirstLevel: " + bInFirstLevel;
4104
+
4105
+ if (bHasGroupLevelCache && bInFirstLevel) {
4106
+ return;
4107
+ }
4108
+
4109
+ QUnit.test(sTitle, function (assert) {
3860
4110
  var fnCancelCallback;
3861
4111
 
3862
4112
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
3863
4113
  $ParentNavigationProperty : "myParent",
4114
+ expandTo : bInFirstLevel ? 25 : /*test defaulting!*/undefined,
3864
4115
  hierarchyQualifier : "X"
3865
4116
  });
3866
4117
  const oGroupLevelCache = {
@@ -3875,11 +4126,14 @@ sap.ui.define([
3875
4126
  oCache.aElements.$byPredicate = {"('42')" : oParentNode};
3876
4127
  oCache.aElements.$count = 5;
3877
4128
  const oCacheMock = this.mock(oCache);
3878
- oCacheMock.expects("createGroupLevelCache").exactly(bHasGroupLevelCache ? 0 : 1)
4129
+ oCacheMock.expects("createGroupLevelCache")
4130
+ .exactly(bHasGroupLevelCache || bInFirstLevel ? 0 : 1)
3879
4131
  .withExactArgs(sinon.match.same(oParentNode)).returns(oGroupLevelCache);
3880
- this.mock(oGroupLevelCache).expects("setEmpty").exactly(bHasGroupLevelCache ? 0 : 1)
4132
+ this.mock(oGroupLevelCache).expects("setEmpty")
4133
+ .exactly(bHasGroupLevelCache || bInFirstLevel ? 0 : 1)
3881
4134
  .withExactArgs();
3882
- this.mock(_Helper).expects("updateAll").exactly(bHasGroupLevelCache ? 0 : 1)
4135
+ this.mock(_Helper).expects("updateAll")
4136
+ .exactly(bHasGroupLevelCache || bInFirstLevel ? 0 : 1)
3883
4137
  .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('42')",
3884
4138
  sinon.match.same(oParentNode), {"@$ui5.node.isExpanded" : true});
3885
4139
  const oEntityData = {
@@ -3888,20 +4142,23 @@ sap.ui.define([
3888
4142
  foo : "~foo~"
3889
4143
  };
3890
4144
  const oPostBody = {};
3891
- this.mock(oGroupLevelCache).expects("create")
4145
+ const oCollectionCache = bInFirstLevel ? oCache.oFirstLevel : oGroupLevelCache;
4146
+ this.mock(oCollectionCache).expects("create")
3892
4147
  .withExactArgs("~oGroupLock~", "~oPostPathPromise~", "~sPath~", "~sTransientPredicate~",
3893
4148
  {bar : "~bar~", foo : "~foo~"},
3894
4149
  false, "~fnErrorCallback~", "~fnSubmitCallback~", sinon.match.func)
3895
4150
  .callsFake(function () {
3896
4151
  fnCancelCallback = arguments[8];
3897
- if (!bHasGroupLevelCache) {
3898
- assert.strictEqual(_Helper.getPrivateAnnotation(oParentNode, "cache"),
3899
- oGroupLevelCache);
3900
- }
4152
+ assert.strictEqual(_Helper.getPrivateAnnotation(oParentNode, "cache"),
4153
+ bInFirstLevel ? undefined : oGroupLevelCache);
3901
4154
  _Helper.setPrivateAnnotation(oEntityData, "postBody", oPostBody);
3902
4155
  return new SyncPromise(function (resolve) {
3903
4156
  setTimeout(function () {
3904
4157
  _Helper.setPrivateAnnotation(oEntityData, "predicate", "('ABC')");
4158
+ if (bInFirstLevel) {
4159
+ // Note: #calculateKeyPredicateRH doesn't know better :-(
4160
+ oEntityData["@$ui5.node.level"] = 1;
4161
+ }
3905
4162
  resolve();
3906
4163
  });
3907
4164
  });
@@ -3909,17 +4166,19 @@ sap.ui.define([
3909
4166
  this.mock(_Helper).expects("makeRelativeUrl").withExactArgs("/Foo('42')", "/Foo")
3910
4167
  .returns("~relativeUrl~");
3911
4168
  oCacheMock.expects("addElements")
3912
- .withExactArgs(sinon.match.same(oEntityData), 3, sinon.match.same(oGroupLevelCache), 0)
4169
+ .withExactArgs(sinon.match.same(oEntityData), 3, sinon.match.same(oCollectionCache))
3913
4170
  .callsFake(function () {
3914
4171
  assert.deepEqual(oCache.aElements, ["0", "1", oParentNode, null, "3", "4"]);
3915
4172
  });
3916
- oCacheMock.expects("shiftIndex").withExactArgs(3, +1);
4173
+ const oAdjustDescendantCountExpectation = oCacheMock.expects("adjustDescendantCount")
4174
+ .exactly(bInFirstLevel ? 1 : 0).withExactArgs(sinon.match.same(oEntityData), 3, +1);
3917
4175
 
3918
4176
  // code under test
3919
4177
  const oResult = oCache.create("~oGroupLock~", "~oPostPathPromise~", "~sPath~",
3920
4178
  "~sTransientPredicate~", oEntityData, /*bAtEndOfCreated*/false, "~fnErrorCallback~",
3921
4179
  "~fnSubmitCallback~");
3922
4180
 
4181
+ assert.strictEqual(oAdjustDescendantCountExpectation.callCount, bInFirstLevel ? 1 : 0);
3923
4182
  assert.deepEqual(oPostBody, {"myParent@odata.bind" : "~relativeUrl~"});
3924
4183
  assert.deepEqual(oEntityData, {
3925
4184
  "@$ui5._" : {postBody : oPostBody},
@@ -3932,6 +4191,12 @@ sap.ui.define([
3932
4191
 
3933
4192
  return oResult.then(function (oEntityData0) {
3934
4193
  assert.strictEqual(oEntityData0, oEntityData);
4194
+ assert.deepEqual(oEntityData, {
4195
+ "@$ui5._" : {postBody : oPostBody, predicate : "('ABC')"},
4196
+ "@$ui5.node.level" : 24,
4197
+ bar : "~bar~",
4198
+ foo : "~foo~"
4199
+ });
3935
4200
  assert.deepEqual(oCache.aElements.$byPredicate, {
3936
4201
  "('42')" : oParentNode,
3937
4202
  "('ABC')" : oEntityData
@@ -3939,14 +4204,11 @@ sap.ui.define([
3939
4204
  assert.strictEqual(oCache.aElements.$count, 6);
3940
4205
 
3941
4206
  oCache.aElements[3] = oEntityData;
3942
- oCacheMock.expects("shiftIndex").withExactArgs(3, -1)
3943
- .callsFake(function () {
3944
- assert.deepEqual(oCache.aElements,
3945
- ["0", "1", oParentNode, oEntityData, "3", "4"], "not yet spliced");
3946
- });
3947
4207
  this.mock(_Helper).expects("getPrivateAnnotation")
3948
4208
  .withExactArgs(sinon.match.same(oEntityData), "transientPredicate")
3949
4209
  .returns("('42')"); // just testing ;-)
4210
+ oCacheMock.expects("adjustDescendantCount").exactly(bInFirstLevel ? 1 : 0)
4211
+ .withExactArgs(sinon.match.same(oEntityData), 3, -1);
3950
4212
 
3951
4213
  // code under test
3952
4214
  fnCancelCallback();
@@ -3958,21 +4220,85 @@ sap.ui.define([
3958
4220
  assert.deepEqual(oCache.aElements, ["0", "1", oParentNode, "3", "4"]);
3959
4221
  }.bind(this));
3960
4222
  });
4223
+ });
3961
4224
  });
3962
4225
 
3963
4226
  //*********************************************************************************************
3964
- QUnit.test("create: expandTo > 1", function (assert) {
4227
+ QUnit.test("create: root node", function (assert) {
4228
+ var fnCancelCallback;
4229
+
3965
4230
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
3966
- expandTo : 2,
4231
+ $ParentNavigationProperty : "myParent",
4232
+ expandTo : 42,
3967
4233
  hierarchyQualifier : "X"
3968
4234
  });
3969
- this.mock(oCache).expects("createGroupLevelCache").never();
3970
- this.mock(_Helper).expects("updateAll").never();
3971
- this.mock(oCache).expects("addElements").never();
4235
+ oCache.aElements = ["0", "1", "2"];
4236
+ oCache.aElements.$byPredicate = {};
4237
+ oCache.aElements.$count = 3;
4238
+ const oCacheMock = this.mock(oCache);
4239
+ oCacheMock.expects("createGroupLevelCache").never();
4240
+ const oEntityData = {
4241
+ bar : "~bar~",
4242
+ foo : "~foo~"
4243
+ };
4244
+ const oPostBody = {};
4245
+ this.mock(oCache.oFirstLevel).expects("create")
4246
+ .withExactArgs("~oGroupLock~", "~oPostPathPromise~", "~sPath~", "~sTransientPredicate~",
4247
+ {bar : "~bar~", foo : "~foo~"},
4248
+ false, "~fnErrorCallback~", "~fnSubmitCallback~", sinon.match.func)
4249
+ .callsFake(function () {
4250
+ fnCancelCallback = arguments[8];
4251
+ _Helper.setPrivateAnnotation(oEntityData, "postBody", oPostBody);
4252
+ return new SyncPromise(function (resolve) {
4253
+ setTimeout(function () {
4254
+ _Helper.setPrivateAnnotation(oEntityData, "predicate", "('ABC')");
4255
+ resolve();
4256
+ });
4257
+ });
4258
+ });
4259
+ this.mock(_Helper).expects("makeRelativeUrl").never();
4260
+ oCacheMock.expects("addElements")
4261
+ .withExactArgs(sinon.match.same(oEntityData), 0, sinon.match.same(oCache.oFirstLevel))
4262
+ .callsFake(function () {
4263
+ assert.deepEqual(oCache.aElements, [null, "0", "1", "2"]);
4264
+ });
3972
4265
 
3973
- assert.throws(function () {
3974
- oCache.create();
3975
- }, new Error("Unsupported expandTo: 2"));
4266
+ // code under test
4267
+ const oResult = oCache.create("~oGroupLock~", "~oPostPathPromise~", "~sPath~",
4268
+ "~sTransientPredicate~", oEntityData, /*bAtEndOfCreated*/false, "~fnErrorCallback~",
4269
+ "~fnSubmitCallback~");
4270
+
4271
+ assert.deepEqual(oPostBody, {});
4272
+ assert.deepEqual(oEntityData, {
4273
+ "@$ui5._" : {postBody : oPostBody},
4274
+ "@$ui5.node.level" : 1,
4275
+ bar : "~bar~",
4276
+ foo : "~foo~"
4277
+ });
4278
+ assert.strictEqual(oCache.aElements.$count, 4);
4279
+ assert.strictEqual(oResult.isPending(), true);
4280
+
4281
+ return oResult.then((oEntityData0) => {
4282
+ assert.strictEqual(oEntityData0, oEntityData);
4283
+ assert.deepEqual(oCache.aElements.$byPredicate, {
4284
+ "('ABC')" : oEntityData
4285
+ });
4286
+ assert.strictEqual(oCache.aElements.$count, 4);
4287
+
4288
+ oCache.aElements[0] = oEntityData;
4289
+ this.mock(_Helper).expects("getPrivateAnnotation")
4290
+ .withExactArgs(sinon.match.same(oEntityData), "transientPredicate")
4291
+ .returns("('42')"); // just testing ;-)
4292
+
4293
+ // code under test
4294
+ fnCancelCallback();
4295
+
4296
+ assert.strictEqual(oCache.aElements.$count, 3);
4297
+ assert.deepEqual(oCache.aElements.$byPredicate, {
4298
+ "('ABC')" : oEntityData
4299
+ });
4300
+ assert.deepEqual(oCache.aElements, ["0", "1", "2"]);
4301
+ });
3976
4302
  });
3977
4303
 
3978
4304
  //*********************************************************************************************
@@ -3985,7 +4311,7 @@ sap.ui.define([
3985
4311
  this.mock(oCache).expects("addElements").never();
3986
4312
 
3987
4313
  assert.throws(function () {
3988
- oCache.create(null, null, "", "", null, /*bAtEndOfCreated*/true);
4314
+ oCache.create(null, null, "", "", {}, /*bAtEndOfCreated*/true);
3989
4315
  }, new Error("Unsupported bAtEndOfCreated"));
3990
4316
 
3991
4317
  oCache.aElements.$byPredicate["('42')"] = {"@$ui5.node.isExpanded" : false};
@@ -3997,7 +4323,7 @@ sap.ui.define([
3997
4323
 
3998
4324
  //*********************************************************************************************
3999
4325
  [false, true].forEach(function (bBreak) {
4000
- QUnit.test(`shiftIndex: break = ${bBreak}`, function (assert) {
4326
+ QUnit.test(`shiftIndex: group level cache, break = ${bBreak}`, function (assert) {
4001
4327
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4002
4328
  hierarchyQualifier : "X"
4003
4329
  });
@@ -4007,8 +4333,8 @@ sap.ui.define([
4007
4333
  ID : "node"
4008
4334
  };
4009
4335
  const oElementSkip = {
4010
- "@$ui5._" : {index : -3, parent : "not oGroupLevelCache", placeholder : true},
4011
- "@$ui5.node.level" : 0, // must be ignored
4336
+ "@$ui5._" : {index : -3, parent : "not oGroupLevelCache"},
4337
+ "@$ui5.node.level" : 25,
4012
4338
  ID : "skip"
4013
4339
  };
4014
4340
  const oElementNoBreak = {
@@ -4018,12 +4344,12 @@ sap.ui.define([
4018
4344
  const oElementChange = {
4019
4345
  "@$ui5._" : {index : 4, parent : "~oGroupLevelCache~"},
4020
4346
  "@$ui5.node.level" : 24,
4021
- ID : "change (node)"
4347
+ ID : "change"
4022
4348
  };
4023
- const oPlaceholderChange = {
4024
- "@$ui5._" : {index : 5, parent : "~oGroupLevelCache~", placeholder : true},
4025
- "@$ui5.node.level" : 0, // must be ignored
4026
- ID : "change (placeholder)"
4349
+ const oElementCreated = {
4350
+ "@$ui5._" : {parent : "~oGroupLevelCache~"},
4351
+ "@$ui5.node.level" : 24,
4352
+ ID : "created"
4027
4353
  };
4028
4354
  const oElementBreak = {
4029
4355
  "@$ui5.node.level" : bBreak
@@ -4037,7 +4363,7 @@ sap.ui.define([
4037
4363
  ID : "trap"
4038
4364
  };
4039
4365
  oCache.aElements = ["0", "1", oNode, oElementSkip, oElementNoBreak, oElementChange,
4040
- oPlaceholderChange, oElementBreak, oElementTrap];
4366
+ oElementCreated, oElementBreak, oElementTrap];
4041
4367
 
4042
4368
  // code under test
4043
4369
  oCache.shiftIndex(2, 47);
@@ -4047,8 +4373,8 @@ sap.ui.define([
4047
4373
  "@$ui5.node.level" : 24,
4048
4374
  ID : "node"
4049
4375
  }, {
4050
- "@$ui5._" : {index : -3, parent : "not oGroupLevelCache", placeholder : true},
4051
- "@$ui5.node.level" : 0,
4376
+ "@$ui5._" : {index : -3, parent : "not oGroupLevelCache"},
4377
+ "@$ui5.node.level" : 25,
4052
4378
  ID : "skip"
4053
4379
  }, {
4054
4380
  "@$ui5.node.level" : 24,
@@ -4056,11 +4382,11 @@ sap.ui.define([
4056
4382
  }, {
4057
4383
  "@$ui5._" : {index : 4 + 47, parent : "~oGroupLevelCache~"},
4058
4384
  "@$ui5.node.level" : 24,
4059
- ID : "change (node)"
4385
+ ID : "change"
4060
4386
  }, {
4061
- "@$ui5._" : {index : 5 + 47, parent : "~oGroupLevelCache~", placeholder : true},
4062
- "@$ui5.node.level" : 0,
4063
- ID : "change (placeholder)"
4387
+ "@$ui5._" : {parent : "~oGroupLevelCache~"},
4388
+ "@$ui5.node.level" : 24,
4389
+ ID : "created"
4064
4390
  }, {
4065
4391
  "@$ui5.node.level" : bBreak ? 23 : 24,
4066
4392
  ID : "break"
@@ -4076,117 +4402,201 @@ sap.ui.define([
4076
4402
  });
4077
4403
  });
4078
4404
 
4405
+ //*********************************************************************************************
4406
+ QUnit.test("shiftIndex: oFirstLevel", function (assert) {
4407
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4408
+ hierarchyQualifier : "X"
4409
+ });
4410
+ oCache.aElements = [{
4411
+ "@$ui5._" : {index : 0, parent : oCache.oFirstLevel}
4412
+ }, {
4413
+ "@$ui5._" : {index : 1, parent : oCache.oFirstLevel}
4414
+ }, {
4415
+ "@$ui5._" : {index : 2, parent : oCache.oFirstLevel}
4416
+ }, {
4417
+ "@$ui5._" : {index : 3, parent : oCache.oFirstLevel}
4418
+ }, {
4419
+ "@$ui5._" : {/*index : undefined,*/parent : oCache.oFirstLevel}
4420
+ }, {
4421
+ "@$ui5._" : {index : 0, parent : "~oGroupLevelCache~"}
4422
+ }, {
4423
+ "@$ui5._" : {index : 1, parent : "~oGroupLevelCache~"}
4424
+ }, {
4425
+ "@$ui5._" : {index : 4, parent : oCache.oFirstLevel}
4426
+ }, {
4427
+ "@$ui5._" : {index : 5, parent : oCache.oFirstLevel}
4428
+ }];
4429
+
4430
+ // code under test
4431
+ oCache.shiftIndex(2, 23);
4432
+
4433
+ assert.deepEqual(oCache.aElements.map((oElement) => oElement["@$ui5._"].index),
4434
+ [0, 1, 2, 3 + 23, undefined, 0, 1, 4 + 23, 5 + 23]);
4435
+ });
4436
+
4079
4437
  //*********************************************************************************************
4080
4438
  [
4081
- {parentLeaf : false, parentExpand : true},
4082
- {parentLeaf : false, parentExpand : false, parentMoved : true},
4083
- {parentLeaf : true, parentExpand : false},
4084
- {noParent : true}
4439
+ {firstLevel : true},
4440
+ {firstLevel : false, parentLeaf : false},
4441
+ {firstLevel : false, parentLeaf : true}
4085
4442
  ].forEach(function (oFixture) {
4086
- QUnit.test(`_delete: leaf, ${JSON.stringify(oFixture)}`, function (assert) {
4087
- // Before the delete, the child is at 2 and the parent is at 1 (or missing) - hence the
4088
- // child's level index is 0 (or 2). When restoring, the level index is 3, and the parent
4089
- // possibly moved to index 6. So the child must be restored to 3 (no parent), 5 (parent
4090
- // still at 1) or 10 (parent moved to 6).
4443
+ [false, true].forEach((bCreated) => {
4444
+ const sTitle = `_delete: ${JSON.stringify(oFixture)}, ${bCreated}`;
4445
+
4446
+ QUnit.test(sTitle, function (assert) {
4447
+ var oCountExpectation, oRemoveExpectation;
4448
+
4091
4449
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4092
4450
  hierarchyQualifier : "X"
4093
4451
  });
4094
4452
  const fnCallback = sinon.spy();
4095
- const oLevelCache = {
4096
- _delete : mustBeMocked,
4097
- getValue : mustBeMocked
4098
- };
4099
- const oParent = {
4100
- "@$ui5.node.isExpanded" : true
4453
+ const oParentCache = {
4454
+ getValue : mustBeMocked,
4455
+ removeElement : mustBeMocked
4101
4456
  };
4102
4457
 
4103
- if (!oFixture.noParent) {
4104
- oCache.aElements[1] = oParent;
4458
+ const oElement = oCache.aElements[2] = {};
4459
+ if (bCreated) { // simulate a created persisted element
4460
+ oElement["@$ui5.context.isTransient"] = false;
4461
+ }
4462
+ oCache.aElements[3] = "~oParent~";
4463
+ if (oFixture.firstLevel) {
4464
+ oCache.oFirstLevel = oParentCache;
4105
4465
  }
4106
- oCache.aElements[2] = "~oElement~";
4107
4466
  const oHelperMock = this.mock(_Helper);
4108
- oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElement~", "parent")
4109
- .returns(oLevelCache);
4110
- oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElement~", "index")
4111
- .returns(oFixture.noParent ? 2 : 0);
4112
- const oLevelCacheMock = this.mock(oLevelCache);
4113
- const oDeleteExpectation = oLevelCacheMock.expects("_delete")
4114
- .withExactArgs("~groupLock~", "~editUrl~", oFixture.noParent ? "2" : "0",
4115
- "~etagEntity~", sinon.match.func)
4116
- .returns("~promise~");
4467
+ oHelperMock.expects("getPrivateAnnotation")
4468
+ .withExactArgs(sinon.match.same(oElement), "parent")
4469
+ .returns(oParentCache);
4470
+ oHelperMock.expects("getPrivateAnnotation")
4471
+ .withExactArgs(sinon.match.same(oElement), "predicate")
4472
+ .returns("~predicate~");
4473
+ this.mock(this.oRequestor).expects("request")
4474
+ .withExactArgs("DELETE", "~editUrl~", "~groupLock~", {
4475
+ "If-Match" : sinon.match.same(oElement)
4476
+ })
4477
+ .callsFake(() => {
4478
+ this.mock(_Cache).expects("getElementIndex")
4479
+ .withExactArgs(sinon.match.same(oCache.aElements), "~predicate~", 2)
4480
+ .returns(4);
4481
+ oHelperMock.expects("getPrivateAnnotation")
4482
+ .withExactArgs(sinon.match.same(oElement), "index", 0).returns("~index~");
4483
+ const oParentCacheMock = this.mock(oParentCache);
4484
+ oRemoveExpectation = oParentCacheMock.expects("removeElement")
4485
+ .withExactArgs("~index~", "~predicate~").returns("~iIndexInParentCache~");
4486
+ oHelperMock.expects("getPrivateAnnotation")
4487
+ .withExactArgs(sinon.match.same(oElement), "descendants", 0)
4488
+ .returns(oFixture.firstLevel ? 3 : 0);
4489
+ oParentCacheMock.expects("removeElement").exactly(oFixture.firstLevel ? 3 : 0)
4490
+ .withExactArgs("~iIndexInParentCache~");
4491
+ this.mock(oCache).expects("adjustDescendantCount")
4492
+ .exactly(oFixture.firstLevel ? 1 : 0)
4493
+ .withExactArgs(sinon.match.same(oElement), 4, oFixture.firstLevel ? -4 : -1);
4494
+ oCountExpectation = this.mock(oParentCache).expects("getValue")
4495
+ .exactly(oFixture.firstLevel ? 0 : 1)
4496
+ .withExactArgs("$count").returns(oFixture.parentLeaf ? 0 : 5);
4497
+ this.mock(oCache).expects("makeLeaf").exactly(oFixture.parentLeaf ? 1 : 0)
4498
+ .withExactArgs("~oParent~");
4499
+ this.mock(oCache).expects("shiftIndex").exactly(bCreated ? 0 : 1)
4500
+ .withExactArgs(4, oFixture.firstLevel ? -4 : -1);
4501
+ this.mock(oCache).expects("removeElement")
4502
+ .withExactArgs(4, "~predicate~");
4503
+
4504
+ return Promise.resolve();
4505
+ });
4117
4506
 
4118
- assert.strictEqual(
4119
- // code under test
4120
- oCache._delete("~groupLock~", "~editUrl~", "2", "~etagEntity~", fnCallback),
4121
- "~promise~");
4507
+ // code under test
4508
+ const oDeletePromise = oCache._delete("~groupLock~", "~editUrl~", "2", "n/a", fnCallback);
4122
4509
 
4123
- const oCacheMock = this.mock(oCache);
4124
- const oShiftExpectation1 = oCacheMock.expects("shiftIndex").withExactArgs(2, -1);
4125
- oHelperMock.expects("getPrivateAnnotation").withExactArgs("~oElement~", "predicate")
4126
- .returns("~predicate~");
4127
- const oRemoveExpectation = oCacheMock.expects("removeElement")
4128
- .withExactArgs(sinon.match.same(oCache.aElements), 2, "~predicate~", "");
4129
- oLevelCacheMock.expects("getValue").exactly(oFixture.noParent ? 0 : 1)
4130
- .withExactArgs("$count").returns(oFixture.parentLeaf ? 0 : 5);
4131
- oHelperMock.expects("getPrivateAnnotation").exactly(oFixture.parentLeaf ? 1 : 0)
4132
- .withExactArgs(sinon.match.same(oParent), "predicate").returns("~predicate~");
4133
- oHelperMock.expects("updateAll").exactly(oFixture.parentLeaf ? 1 : 0)
4134
- .withExactArgs(sinon.match.same(oCache.mChangeListeners), "~predicate~",
4135
- sinon.match.same(oParent), {"@$ui5.node.isExpanded" : undefined});
4510
+ assert.ok(oDeletePromise.isPending(), "a SyncPromise");
4136
4511
 
4137
- // code under test - callback deleting
4138
- oDeleteExpectation.firstCall.args[4](0, -1);
4512
+ return oDeletePromise.then(function () {
4513
+ assert.strictEqual(fnCallback.callCount, 1);
4514
+ assert.deepEqual(fnCallback.args[0], [4, -1]);
4515
+ assert.ok(oRemoveExpectation.calledBefore(oCountExpectation));
4516
+ });
4517
+ });
4518
+ });
4519
+ });
4139
4520
 
4140
- if (oFixture.parentMoved) {
4141
- delete oCache.aElements[1];
4142
- oCache.aElements[6] = oParent;
4143
- }
4144
- assert.ok(oShiftExpectation1.calledBefore(oRemoveExpectation));
4145
- assert.strictEqual(fnCallback.callCount, 1);
4146
- assert.deepEqual(fnCallback.args[0], [2, -1]);
4147
- if (oFixture.parentLeaf) {
4148
- assert.notOk("@$ui5.node.isExpanded" in oParent);
4149
- }
4521
+ //*********************************************************************************************
4522
+ QUnit.test("_delete: request fails", function (assert) {
4523
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4524
+ hierarchyQualifier : "X"
4525
+ });
4526
+ const fnCallback = sinon.spy();
4527
+ const oElement = {};
4150
4528
 
4151
- // parent index is 6 or 1, child index in level cache is 3 (from the callback)
4152
- let iExpectedIndex = oFixture.parentMoved ? 10 : 5;
4153
- if (oFixture.noParent) {
4154
- iExpectedIndex = 3;
4155
- }
4156
- const oRestoreExpectation = this.mock(oCache).expects("restoreElement")
4157
- .withExactArgs(sinon.match.same(oCache.aElements), iExpectedIndex, "~oElement~", "");
4158
- const oShiftExpectation2 = oCacheMock.expects("shiftIndex")
4159
- .withExactArgs(iExpectedIndex, 1);
4160
- oLevelCacheMock.expects("getValue").exactly(oFixture.noParent ? 0 : 1)
4161
- .withExactArgs("$count").returns(oFixture.parentExpand ? 1 : 5);
4162
- oHelperMock.expects("getPrivateAnnotation").exactly(oFixture.parentExpand ? 1 : 0)
4163
- .withExactArgs(sinon.match.same(oParent), "predicate").returns("~predicate~");
4164
- oHelperMock.expects("updateAll").exactly(oFixture.parentExpand ? 1 : 0)
4165
- .withExactArgs(sinon.match.same(oCache.mChangeListeners), "~predicate~",
4166
- sinon.match.same(oParent), {"@$ui5.node.isExpanded" : true});
4167
- oHelperMock.expects("setPrivateAnnotation").withExactArgs("~oElement~", "index", 3);
4529
+ oCache.aElements[2] = oElement;
4530
+ this.mock(this.oRequestor).expects("request")
4531
+ .withExactArgs("DELETE", "~editUrl~", "~groupLock~",
4532
+ {"If-Match" : sinon.match.same(oElement)})
4533
+ .returns(Promise.reject("~error~"));
4534
+
4535
+ // code under test
4536
+ const oDeletePromise = oCache._delete("~groupLock~", "~editUrl~", "2", "n/a", fnCallback);
4168
4537
 
4169
- // code under test - callback reinserting
4170
- oDeleteExpectation.firstCall.args[4](3, 1);
4538
+ assert.ok(oDeletePromise.isPending(), "a SyncPromise");
4171
4539
 
4172
- assert.ok(oRestoreExpectation.calledBefore(oShiftExpectation2));
4173
- assert.strictEqual(fnCallback.callCount, 2);
4174
- assert.deepEqual(fnCallback.args[1], [iExpectedIndex, 1]);
4540
+ return oDeletePromise.then(function () {
4541
+ assert.ok(false);
4542
+ }, function (oError) {
4543
+ assert.strictEqual(oError, "~error~");
4544
+ assert.strictEqual(fnCallback.callCount, 0);
4545
+ });
4175
4546
  });
4176
- });
4177
4547
 
4178
4548
  //*********************************************************************************************
4179
- QUnit.test("_delete: expandTo > 1", function (assert) {
4549
+ QUnit.test("_delete: transient node", function (assert) {
4550
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4551
+ hierarchyQualifier : "X"
4552
+ });
4553
+ const oElement = {
4554
+ "@$ui5.context.isTransient" : true
4555
+ };
4556
+ const oParentCache = {
4557
+ _delete : mustBeMocked
4558
+ };
4559
+
4560
+ oCache.aElements[2] = oElement;
4561
+ const oHelperMock = this.mock(_Helper);
4562
+ oHelperMock.expects("getPrivateAnnotation")
4563
+ .withExactArgs(sinon.match.same(oElement), "predicate").returns("n/a");
4564
+ oHelperMock.expects("getPrivateAnnotation")
4565
+ .withExactArgs(sinon.match.same(oElement), "parent")
4566
+ .returns(oParentCache);
4567
+ oHelperMock.expects("getPrivateAnnotation")
4568
+ .withExactArgs(sinon.match.same(oElement), "transientPredicate")
4569
+ .returns("~transientPredicate~");
4570
+ this.mock(oParentCache).expects("_delete")
4571
+ .withExactArgs("~groupLock~", "~editUrl~", "~transientPredicate~")
4572
+ .returns("~promise~");
4573
+
4574
+ assert.strictEqual(
4575
+ // code under test
4576
+ oCache._delete("~groupLock~", "~editUrl~", "2"),
4577
+ "~promise~"
4578
+ );
4579
+ });
4580
+
4581
+ //*********************************************************************************************
4582
+ QUnit.test("_delete: expanded node", function (assert) {
4180
4583
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4181
- expandTo : 2,
4182
4584
  hierarchyQualifier : "X"
4183
4585
  });
4586
+ const oElement = {
4587
+ "@$ui5.node.isExpanded" : true
4588
+ };
4589
+ oCache.aElements[2] = oElement;
4590
+
4591
+ this.mock(_Helper).expects("getPrivateAnnotation")
4592
+ .withExactArgs(sinon.match.same(oElement), "predicate").returns("(42)");
4593
+ this.mock(this.oRequestor).expects("request").never();
4184
4594
  this.mock(oCache).expects("removeElement").never();
4185
4595
  this.mock(_Helper).expects("updateAll").never();
4186
4596
 
4187
4597
  assert.throws(function () {
4188
- oCache._delete();
4189
- }, new Error("Unsupported expandTo: 2"));
4598
+ oCache._delete("~oGroupLock~", "edit/url", "2");
4599
+ }, new Error("Unsupported expanded node: Foo(42)"));
4190
4600
  });
4191
4601
 
4192
4602
  //*********************************************************************************************
@@ -4219,4 +4629,81 @@ sap.ui.define([
4219
4629
  // code under test
4220
4630
  oCache.resetChangesForPath("~sPath~");
4221
4631
  });
4632
+
4633
+ //*********************************************************************************************
4634
+ // in: array of arrays with level, descendants
4635
+ // isAncestorOf gives the expected calls of the function and its results
4636
+ // leaf: index of a node becoming a leaf
4637
+ // out: array of descendants values
4638
+ [{
4639
+ // Placeholder at 3 must be ignored, 2 and 1 are ancestors, 0 must never be looked at
4640
+ // Note: level -1 is unrealistic, but enforces that the loop stops at level 1
4641
+ in : [[-1, 0], [1, 30], [2, 29], [0, undefined], [3, 0], [3, 1]],
4642
+ isAncestorOf : [[2, 5, true]],
4643
+ out : [0, 7, 6, undefined, 0, 1]
4644
+ }, { // Placeholder at 2 must be ignored, but 1 is no ancestor
4645
+ in : [[1, 30], [2, 0], [0, undefined], [3, 1]],
4646
+ isAncestorOf : [[1, 3, false], [0, 3, true]],
4647
+ out : [7, 0, undefined, 1]
4648
+ }, { // nothing to do, no visible ancestor
4649
+ in : [[1, 8]],
4650
+ out : [8]
4651
+ }, { // root becomes leaf
4652
+ in : [[1, 23], [2, 0]],
4653
+ leaf : 0,
4654
+ out : [0, 0]
4655
+ }, { // 1 becomes leaf
4656
+ in : [[1, 24], [2, 23], [3, 0]],
4657
+ leaf : 1,
4658
+ out : [1, 0, 0]
4659
+ }].forEach(function (oFixture, i) {
4660
+ QUnit.test("adjustDescendantCount #" + i, function (assert) {
4661
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4662
+ hierarchyQualifier : "X"
4663
+ });
4664
+ oCache.aElements = oFixture.in.map(([iLevel, iDescendants]) => ({
4665
+ "@$ui5._" : {descendants : iDescendants},
4666
+ "@$ui5.node.level" : iLevel
4667
+ }));
4668
+
4669
+ const oCacheMock = this.mock(oCache);
4670
+ if (oFixture.isAncestorOf) {
4671
+ oFixture.isAncestorOf.forEach(([iIndex0, iIndex1, bResult]) => {
4672
+ oCacheMock.expects("isAncestorOf").withExactArgs(iIndex0, iIndex1).returns(bResult);
4673
+ });
4674
+ } else {
4675
+ oCacheMock.expects("isAncestorOf").never();
4676
+ }
4677
+ oCacheMock.expects("makeLeaf").exactly("leaf" in oFixture ? 1 : 0)
4678
+ .withExactArgs(sinon.match.same(oCache.aElements[oFixture.leaf]));
4679
+
4680
+ const iIndex = oFixture.in.length - 1;
4681
+ // code under test
4682
+ oCache.adjustDescendantCount(oCache.aElements[iIndex], iIndex, -23);
4683
+
4684
+ assert.deepEqual(
4685
+ oCache.aElements.map((oElement) => oElement["@$ui5._"].descendants),
4686
+ oFixture.out);
4687
+ });
4688
+ });
4689
+
4690
+ //*********************************************************************************************
4691
+ QUnit.test("makeLeaf", function (assert) {
4692
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4693
+ hierarchyQualifier : "X"
4694
+ });
4695
+ const oElement = {"@$ui5.node.isExpanded" : true};
4696
+
4697
+ this.mock(_Helper).expects("getPrivateAnnotation")
4698
+ .withExactArgs(sinon.match.same(oElement), "predicate")
4699
+ .returns("~predicate~");
4700
+ this.mock(_Helper).expects("updateAll")
4701
+ .withExactArgs(sinon.match.same(oCache.mChangeListeners), "~predicate~",
4702
+ sinon.match.same(oElement), {"@$ui5.node.isExpanded" : undefined});
4703
+
4704
+ // code under test
4705
+ oCache.makeLeaf(oElement);
4706
+
4707
+ assert.notOk("@$ui5.node.isExpanded" in oElement);
4708
+ });
4222
4709
  });