@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
@@ -4,7 +4,6 @@
4
4
  sap.ui.define([
5
5
  "sap/base/Log",
6
6
  "sap/base/util/uid",
7
- "sap/base/util/UriParameters",
8
7
  "sap/m/ColumnListItem",
9
8
  "sap/m/CustomListItem",
10
9
  "sap/m/FlexBox",
@@ -16,6 +15,7 @@ sap.ui.define([
16
15
  "sap/ui/core/Configuration",
17
16
  "sap/ui/core/Messaging",
18
17
  "sap/ui/core/Rendering",
18
+ "sap/ui/core/Supportability",
19
19
  "sap/ui/core/mvc/Controller",
20
20
  "sap/ui/core/mvc/View",
21
21
  "sap/ui/model/ChangeReason",
@@ -31,15 +31,16 @@ sap.ui.define([
31
31
  "sap/ui/model/odata/v4/ODataPropertyBinding",
32
32
  "sap/ui/model/odata/v4/ValueListType",
33
33
  "sap/ui/model/odata/v4/lib/_Helper",
34
+ "sap/ui/security/Security",
34
35
  "sap/ui/test/TestUtils",
35
36
  "sap/ui/util/XMLHelper",
36
37
  // load Table resources upfront to avoid loading times > 1 second for the first test using Table
37
38
  "sap/ui/table/Table"
38
- ], function (Log, uid, UriParameters, ColumnListItem, CustomListItem, FlexBox, _MessageStrip, Text,
39
- Device, EventProvider, SyncPromise, Configuration, Messaging, Rendering, Controller, View,
40
- ChangeReason, Filter, FilterOperator, FilterType, Sorter, OperationMode, AnnotationHelper,
41
- ODataListBinding, ODataMetaModel, ODataModel, ODataPropertyBinding, ValueListType, _Helper,
42
- TestUtils, XMLHelper) {
39
+ ], function (Log, uid, ColumnListItem, CustomListItem, FlexBox, _MessageStrip, Text,
40
+ Device, EventProvider, SyncPromise, Configuration, Messaging, Rendering, Supportability,
41
+ Controller, View, ChangeReason, Filter, FilterOperator, FilterType, Sorter, OperationMode,
42
+ AnnotationHelper, ODataListBinding, ODataMetaModel, ODataModel, ODataPropertyBinding,
43
+ ValueListType, _Helper, Security, TestUtils, XMLHelper) {
43
44
  /*eslint no-sparse-arrays: 0, "max-len": ["error", {"code": 100,
44
45
  "ignorePattern": "/sap/opu/odata4/|\" :$|\" : \\{$|\\{meta>"}], */
45
46
  "use strict";
@@ -56,7 +57,7 @@ sap.ui.define([
56
57
  rSkip = /&\$skip=(\d+)/, // $skip=<number>
57
58
  sTeaBusi = "/sap/opu/odata4/IWBEP/TEA/default/IWBEP/TEA_BUSI/0001/",
58
59
  // the timeout for the tests and for waitForChanges in millseconds, 0 = keep defaults
59
- iTestTimeout = parseInt(UriParameters.fromQuery(window.location.search).get("timeout")),
60
+ iTestTimeout = parseInt(new URLSearchParams(window.location.search).get("timeout")),
60
61
  rTop = /&\$top=(\d+)/, // $top=<number>
61
62
  rTransientPredicate = /\(\$uid=[-\w]+\)/g;
62
63
 
@@ -121,22 +122,32 @@ sap.ui.define([
121
122
  } // else: do not spam the output ;-)
122
123
  }
123
124
 
124
- function visitElements(aElements, bSkipByPredicate = false, iLevelOffset = 0) {
125
- aElements.forEach((oElement) => {
126
- const iIndex = _Helper.getPrivateAnnotation(oElement, "index");
125
+ function visitElements(aElements, bSkipByPredicate = false, iLevelOffset = 0,
126
+ iIndexOffset = 0) {
127
+ aElements.forEach((oElement, i) => {
128
+ let iIndex = _Helper.getPrivateAnnotation(oElement, "index");
127
129
  // Note: "@$ui5.node.level" is outdated after #move!
128
130
  const iLevel = oElement["@$ui5.node.level"] + iLevelOffset;
129
131
  const oParent = aParentByLevel[iLevel];
132
+ if (oParent === aParentByLevel[0] && iIndex !== undefined) {
133
+ iIndex += iIndexOffset;
134
+ }
130
135
  const bPlaceholder = _Helper.hasPrivateAnnotation(oElement, "placeholder");
131
136
 
132
137
  if (oParent) {
133
138
  strictEqual(_Helper.getPrivateAnnotation(oElement, "parent"), oParent,
134
- `${sTitle}: "parent" @ level ${iLevel}, index ${iIndex}`);
135
- strictEqual(oParent.aElements.indexOf(oElement),
136
- bPlaceholder
137
- ? -1
138
- : iIndex,
139
- `${sTitle}: "index" @ level ${iLevel}, index ${iIndex}`);
139
+ `${sTitle}: "parent" @ level ${iLevel}, #${i}`);
140
+ if ("@$ui5.context.isTransient" in oElement) {
141
+ strictEqual(iIndex, undefined,
142
+ `${sTitle}: created persisted @ level ${iLevel}, #${i}`);
143
+ } else if (bPlaceholder) {
144
+ strictEqual(oParent.aElements.indexOf(oElement), -1,
145
+ `${sTitle}: placeholder @ level ${iLevel}, #${i}`);
146
+ } else {
147
+ strictEqual(iIndex,
148
+ oParent.aElements.indexOf(oElement) - oParent.aElements.$created,
149
+ `${sTitle}: $skip index @ level ${iLevel}, #${i}`);
150
+ }
140
151
  } else {
141
152
  assert.ok(false, `${sTitle}: no known parent for level ${iLevel}`);
142
153
  }
@@ -163,7 +174,8 @@ sap.ui.define([
163
174
 
164
175
  const aSpliced = _Helper.getPrivateAnnotation(oElement, "spliced");
165
176
  if (aSpliced) {
166
- visitElements(aSpliced, true, iLevel + 1 - aSpliced[0]["@$ui5.node.level"]);
177
+ visitElements(aSpliced, true, iLevel + 1 - aSpliced[0]["@$ui5.node.level"],
178
+ iIndex - aSpliced.$index);
167
179
  }
168
180
  });
169
181
  }
@@ -177,7 +189,11 @@ sap.ui.define([
177
189
  true, `${sTitle}: $byPredicate[${sPredicate}] in aElements`);
178
190
  }
179
191
 
180
- for (let i = 0, n = oListBinding.getAggregation().expandTo || 1; i <= n; i += 1) {
192
+ let iExpandTo = oListBinding.getAggregation().expandTo || 1;
193
+ if (iExpandTo === Number.MAX_SAFE_INTEGER) {
194
+ iExpandTo = 99; // avoid "Invalid array length" :-)
195
+ }
196
+ for (let i = 0; i <= iExpandTo; i += 1) {
181
197
  // Note: level 0 or 1 is used for initial placeholders of 1st level cache!
182
198
  aParentByLevel[i] = oListBinding.oCache.oFirstLevel;
183
199
  }
@@ -224,6 +240,9 @@ sap.ui.define([
224
240
  return vText !== undefined ? String(vText) : "";
225
241
  });
226
242
  });
243
+ while (aExpectedContent.length < aRows.length) { // pad with "empty" rows
244
+ aExpectedContent.push(aExpectedContent[0].slice().fill(""));
245
+ }
227
246
  assert.deepEqual(aRows.map(function (oRow) {
228
247
  return oRow.getCells().map(function (oCell) {
229
248
  return oCell.getText ? oCell.getText() : oCell.getValue();
@@ -476,7 +495,8 @@ sap.ui.define([
476
495
  oDocument = XMLHelper.parse(
477
496
  '<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:plugins="sap.m.plugins"'
478
497
  + ' xmlns:t="sap.ui.table" xmlns:trm="sap.ui.table.rowmodes"'
479
- + ' xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1">'
498
+ + ' xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1"'
499
+ + (sViewXML.startsWith(" template:require") ? "" : ">")
480
500
  + sViewXML
481
501
  + "</mvc:View>",
482
502
  "application/xml"
@@ -2326,7 +2346,7 @@ sap.ui.define([
2326
2346
  dRetryAfter = new Date(),
2327
2347
  sView = '<Text text="{/EMPLOYEES(\'1\')/ID}"/>';
2328
2348
 
2329
- this.mock(Configuration).expects("getStatisticsEnabled").withExactArgs()
2349
+ this.mock(Supportability).expects("isStatisticsEnabled").withExactArgs()
2330
2350
  .returns(true);
2331
2351
  oModel = this.createModel("/sap/statistics/", {groupId : "$direct"}, {
2332
2352
  "/sap/statistics/$metadata?sap-statistics=true"
@@ -2389,7 +2409,7 @@ sap.ui.define([
2389
2409
  QUnit.test("sap-statistics for $batch", function (assert) {
2390
2410
  var oModel;
2391
2411
 
2392
- this.mock(Configuration).expects("getStatisticsEnabled").withExactArgs().returns(true);
2412
+ this.mock(Supportability).expects("isStatisticsEnabled").withExactArgs().returns(true);
2393
2413
  oModel = this.createModel("/sap/statistics/", {earlyRequests : true}, {
2394
2414
  "HEAD /sap/statistics/?sap-statistics=true" : {},
2395
2415
  "/sap/statistics/$metadata?sap-statistics=true"
@@ -4812,7 +4832,6 @@ sap.ui.define([
4812
4832
 
4813
4833
  that.expectRequest({
4814
4834
  batchNo : 2,
4815
- method : "GET",
4816
4835
  url : "SalesOrderList('1')/SO_2_SOITEM('0010')/SOITEM_2_PRODUCT"
4817
4836
  + "?sap-client=123&$select=ProductID"
4818
4837
  + "&$expand=PRODUCT_2_BP($select=BusinessPartnerID,CompanyName)"
@@ -4826,7 +4845,6 @@ sap.ui.define([
4826
4845
  })
4827
4846
  .expectRequest({
4828
4847
  batchNo : 2,
4829
- method : "GET",
4830
4848
  url : "SalesOrderList('1')/SO_2_SOITEM('0010')?sap-client=123"
4831
4849
  + "&$select=SOITEM_2_SCHDL"
4832
4850
  + "&$expand=SOITEM_2_SCHDL($select=ItemKey,ScheduleKey)"
@@ -6357,8 +6375,9 @@ sap.ui.define([
6357
6375
  // JIRA: CPOUI5ODATAV4-121
6358
6376
  testXMLTemplating("Operation parameters with sap.ui.model.odata.v4.AnnotationHelper.format",
6359
6377
  "createTeaBusiModel",
6360
- '<template:alias name="format" value="sap.ui.model.odata.v4.AnnotationHelper.format">\
6361
- <template:alias name="value" value="sap.ui.model.odata.v4.AnnotationHelper.value">\
6378
+ ' template:require="{\'AnnotationHelper\':\'sap/ui/model/odata/v4/AnnotationHelper\'}">\
6379
+ <template:alias name="format" value="AnnotationHelper.format">\
6380
+ <template:alias name="value" value="AnnotationHelper.value">\
6362
6381
  <FlexBox id="form" binding="{/ChangeTeamBudgetByID(...)}">\
6363
6382
  <FlexBox binding="{$Parameter}">\
6364
6383
  <template:repeat list="{meta>/ChangeTeamBudgetByID/$Action/0/$Parameter}" var="param">\
@@ -6408,7 +6427,8 @@ sap.ui.define([
6408
6427
  testXMLTemplating(
6409
6428
  "Annotations on operations and parameters sap.ui.model.odata.v4.AnnotationHelper.format",
6410
6429
  "createSpecialCasesModel",
6411
- '<template:alias name="format" value="sap.ui.model.odata.v4.AnnotationHelper.format">\
6430
+ ' template:require="{\'AnnotationHelper\':\'sap/ui/model/odata/v4/AnnotationHelper\'}">\
6431
+ <template:alias name="format" value="AnnotationHelper.format">\
6412
6432
  <FlexBox binding="{special.cases.SendAutograph(...)}"\
6413
6433
  visible="{meta>/Artists/special.cases.SendAutograph\
6414
6434
  @Org.OData.Core.V1.OperationAvailable@@format}">\
@@ -7022,7 +7042,6 @@ sap.ui.define([
7022
7042
  })
7023
7043
  .expectRequest({
7024
7044
  batchNo : 2,
7025
- method : "GET",
7026
7045
  url : "SalesOrderList?$select=SalesOrderID"
7027
7046
  + "&$filter=not (SalesOrderID eq '0500000002'"
7028
7047
  + " or SalesOrderID eq '0500000003')"
@@ -7074,7 +7093,6 @@ sap.ui.define([
7074
7093
  })
7075
7094
  .expectRequest({
7076
7095
  batchNo : 2,
7077
- method : "GET",
7078
7096
  url : "SalesOrderList?$select=SalesOrderID"
7079
7097
  + "&$filter=not (SalesOrderID eq '0500000002')&$skip=2&$top=4"
7080
7098
  }, {
@@ -7716,7 +7734,7 @@ sap.ui.define([
7716
7734
  assert.strictEqual(fnSpy.callCount, 1, "1st #fetchUI5Type");
7717
7735
  assert.strictEqual(oType.getConstraints().maxLength, 40,
7718
7736
  "Don't try this at home, kids!");
7719
- sap.ui.test.TestUtils.withNormalizedMessages(function () {
7737
+ TestUtils.withNormalizedMessages(function () {
7720
7738
  assert.throws(function () {
7721
7739
  oType.validateValue("0123456789012345678901234567890123456789+");
7722
7740
  }, /EnterTextMaxLength 40/);
@@ -7734,7 +7752,7 @@ sap.ui.define([
7734
7752
  assert.strictEqual(fnSpy.callCount, 2, "2nd #fetchUI5Type");
7735
7753
  assert.strictEqual(oType.getConstraints().maxLength, 16,
7736
7754
  "Don't try this at home, kids!");
7737
- sap.ui.test.TestUtils.withNormalizedMessages(function () {
7755
+ TestUtils.withNormalizedMessages(function () {
7738
7756
  assert.throws(function () {
7739
7757
  oType.validateValue("0123456789ABCDEF+");
7740
7758
  }, /EnterTextMaxLength 16/);
@@ -7743,6 +7761,43 @@ sap.ui.define([
7743
7761
  });
7744
7762
  });
7745
7763
 
7764
+ //*********************************************************************************************
7765
+ // Scenario: Show properties of various entities in a collection-valued navigation property. The
7766
+ // application in the incident even used different navigation properties via dynamically created
7767
+ // paths based on data it loaded before.
7768
+ // BCP: 2370133257
7769
+ QUnit.test("BCP: 2370133257", async function (assert) {
7770
+ const oModel = this.createSalesOrdersModel({autoExpandSelect : true});
7771
+ const sView = `
7772
+ <FlexBox id="order" binding="{/SalesOrderList('1')}">
7773
+ <Text id="id" text="{SalesOrderID}"/>
7774
+ </FlexBox>
7775
+ <FlexBox id="item">
7776
+ <Text id="note10" text="{SO_2_SOITEM(SalesOrderID='1',ItemPosition='10')/Note}"/>
7777
+ <Text id="note20" text="{SO_2_SOITEM(SalesOrderID='1',ItemPosition='20')/Note}"/>
7778
+ </FlexBox>`;
7779
+
7780
+ this.expectRequest("SalesOrderList('1')?$select=SalesOrderID", {SalesOrderID : "1"})
7781
+ .expectChange("id", "1")
7782
+ .expectChange("note10")
7783
+ .expectChange("note20");
7784
+
7785
+ await this.createView(assert, sView, oModel);
7786
+
7787
+ this.expectRequest(
7788
+ "SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='10')/Note",
7789
+ {value : "Note #10"})
7790
+ .expectRequest(
7791
+ "SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='20')/Note",
7792
+ {value : "Note #20"})
7793
+ .expectChange("note10", "Note #10")
7794
+ .expectChange("note20", "Note #20");
7795
+
7796
+ this.oView.byId("item").setBindingContext(this.oView.byId("order").getBindingContext());
7797
+
7798
+ await this.waitForChanges(assert);
7799
+ });
7800
+
7746
7801
  //*********************************************************************************************
7747
7802
  // Scenario: Modify a property which does not belong to the parent binding's entity, but is
7748
7803
  // related via a navigation property.
@@ -19802,7 +19857,6 @@ sap.ui.define([
19802
19857
  }, createErrorInsideBatch())
19803
19858
  .expectRequest({
19804
19859
  batchNo : 7, // from the binding's reset due to the failed DELETE
19805
- method : "GET",
19806
19860
  url : "SalesOrderList?$count=true"
19807
19861
  + "&$filter=(LifecycleStatus eq 'N') and not (SalesOrderID eq '2')"
19808
19862
  + "&$select=GrossAmount,SalesOrderID&$orderby=GrossAmount&$skip=0&$top=4"
@@ -21045,6 +21099,11 @@ sap.ui.define([
21045
21099
  groupLevels : ["LifecycleStatus"]
21046
21100
  }
21047
21101
  });
21102
+
21103
+ assert.throws(function () {
21104
+ // code under test (JIRA: CPOUI5ODATAV4-2337)
21105
+ oListBinding.getHeaderContext().isAncestorOf(/*don't care*/);
21106
+ }, new Error("Missing recursive hierarchy"));
21048
21107
  });
21049
21108
  });
21050
21109
 
@@ -24789,7 +24848,7 @@ sap.ui.define([
24789
24848
  // JIRA: CPOUI5ODATAV4-1643
24790
24849
  //
24791
24850
  // Request various side effects that do not affect the hierarchy (JIRA: CPOUI5ODATAV4-1785).
24792
- // Check that create, delete, and refresh are not supported (JIRA: CPOUI5ODATAV4-1851).
24851
+ // Check that refresh is not supported (JIRA: CPOUI5ODATAV4-1851).
24793
24852
  // Additionally, ODLB#getDownloadUrl is tested (JIRA: CPOUI5ODATAV4-1920, BCP: 2370011296).
24794
24853
  // Retrieve "DistanceFromRoot" property path via ODLB#getAggregation (JIRA: CPOUI5ODATAV4-1961).
24795
24854
  //
@@ -24804,7 +24863,7 @@ sap.ui.define([
24804
24863
  // expanded to reveal the kept-alive node.
24805
24864
  // JIRA: CPOUI5ODATAV4-2030
24806
24865
  //
24807
- // The whole tree is expanded to two levels (JIRA: CPOUI5ODATAV4-2095).
24866
+ // The whole tree is expanded to -two-all levels (JIRA: CPOUI5ODATAV4-2095/-2151).
24808
24867
  // Selection keeps a context implicitly alive (JIRA: CPOUI5ODATAV4-2053).
24809
24868
  // Ensure that unchanged $$aggregation is ignored (BCP: 2370045709).
24810
24869
  //
@@ -24818,7 +24877,7 @@ sap.ui.define([
24818
24877
  var sExpectedDownloadUrl
24819
24878
  = "/special/cases/Artists?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
24820
24879
  + "HierarchyNodes=$root/Artists,HierarchyQualifier='OrgChart'"
24821
- + ",NodeProperty='_/NodeID',Levels=999)"
24880
+ + ",NodeProperty='_/NodeID')"
24822
24881
  + "&$select=ArtistID,IsActiveEntity,_/DistanceFromRoot,_/DrillState,_/NodeID"
24823
24882
  + "&$expand=BestFriend($select=ArtistID,IsActiveEntity,Name)",
24824
24883
  oHeaderContext,
@@ -24896,6 +24955,17 @@ sap.ui.define([
24896
24955
  assert.strictEqual(oListBinding.getDownloadUrl(), sExpectedDownloadUrl,
24897
24956
  "JIRA: CPOUI5ODATAV4-1920, CPOUI5ODATAV4-2275");
24898
24957
 
24958
+ assert.throws(function () {
24959
+ // code under test (JIRA: CPOUI5ODATAV4-2337)
24960
+ oHeaderContext.isAncestorOf(oRoot);
24961
+ }, new Error("Not currently part of a recursive hierarchy: /Artists"));
24962
+ assert.throws(function () {
24963
+ // code under test (JIRA: CPOUI5ODATAV4-2337)
24964
+ oRoot.isAncestorOf(oHeaderContext);
24965
+ }, new Error("Not currently part of a recursive hierarchy: /Artists"));
24966
+ // code under test
24967
+ assert.strictEqual(oRoot.isAncestorOf(oRoot), true, "JIRA: CPOUI5ODATAV4-2337");
24968
+
24899
24969
  checkTable("root is leaf", assert, oTable, [
24900
24970
  "/Artists(ArtistID='0',IsActiveEntity=true)"
24901
24971
  ], [
@@ -25295,7 +25365,7 @@ sap.ui.define([
25295
25365
  batchNo : 9,
25296
25366
  url : "Artists?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
25297
25367
  + "HierarchyNodes=$root/Artists,HierarchyQualifier='OrgChart'"
25298
- + ",NodeProperty='_/NodeID',Levels=2)&$select=ArtistID,IsActiveEntity"
25368
+ + ",NodeProperty='_/NodeID')&$select=ArtistID,IsActiveEntity"
25299
25369
  + ",_/DescendantCount,_/DistanceFromRoot,_/DrillState,_/NodeID"
25300
25370
  + "&$expand=BestFriend($select=ArtistID,IsActiveEntity,Name)"
25301
25371
  + "&$count=true&$skip=0&$top=3"
@@ -25333,7 +25403,7 @@ sap.ui.define([
25333
25403
  // code under test
25334
25404
  // Note: overall count must not change here, just the "expansion state"
25335
25405
  oListBinding.setAggregation({
25336
- expandTo : 2,
25406
+ expandTo : Number.MAX_SAFE_INTEGER,
25337
25407
  hierarchyQualifier : "OrgChart"
25338
25408
  });
25339
25409
 
@@ -25368,16 +25438,17 @@ sap.ui.define([
25368
25438
  // no additional request for same aggregation data
25369
25439
  // code under test (BCP: 2370045709)
25370
25440
  oListBinding.setAggregation({
25371
- expandTo : 2,
25441
+ expandTo : Number.MAX_SAFE_INTEGER,
25372
25442
  hierarchyQualifier : "OrgChart"
25373
25443
  });
25374
25444
  // code under test (BCP: 2370045709)
25375
25445
  oListBinding.changeParameters({
25376
25446
  $$aggregation : {
25377
- expandTo : 2,
25447
+ expandTo : Number.MAX_SAFE_INTEGER,
25378
25448
  hierarchyQualifier : "OrgChart"
25379
25449
  }
25380
25450
  });
25451
+ assert.strictEqual(oListBinding.getAggregation().expandTo, Number.MAX_SAFE_INTEGER);
25381
25452
  });
25382
25453
  });
25383
25454
  });
@@ -25689,7 +25760,7 @@ sap.ui.define([
25689
25760
  sTeaBusi + "TEAMS('42')/TEAM_2_EMPLOYEES"
25690
25761
  + "?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
25691
25762
  + "HierarchyNodes=$root/TEAMS('42')/TEAM_2_EMPLOYEES"
25692
- + ",HierarchyQualifier='OrgChart',NodeProperty='ID',Levels=999)"
25763
+ + ",HierarchyQualifier='OrgChart',NodeProperty='ID')"
25693
25764
  + "&$select=DistanceFromRoot,DrillState,ID,MANAGER_ID,SALARY/BONUS_CURR"
25694
25765
  + ",SALARY/YEARLY_BONUS_AMOUNT,TEAM_ID",
25695
25766
  "JIRA: CPOUI5ODATAV4-1920, CPOUI5ODATAV4-2275");
@@ -25856,10 +25927,17 @@ sap.ui.define([
25856
25927
  // Additionally ODLB#getDownloadUrl is tested w/ sort.
25857
25928
  // JIRA: CPOUI5ODATAV4-1920
25858
25929
  // BCP: 2370011296
25930
+ //
25931
+ // While the root node 0 (Alpha) is still collapsed, a new root 9 (Aleph) is created and a side
25932
+ // effect for all rows (within the same $batch, JIRA: CPOUI5ODATAV4-2380) turns spliced nodes
25933
+ // into placeholders. Then 0 (Alpha) is expanded again and we scroll down to check that
25934
+ // placeholders still cause proper requests w.r.t. indices.
25935
+ // JIRA: CPOUI5ODATAV4-2355
25859
25936
  QUnit.test("Recursive Hierarchy: expand to 2, collapse & expand root etc.", function (assert) {
25860
25937
  var oCollapsed,
25861
25938
  oListBinding,
25862
25939
  oModel = this.createTeaBusiModel({autoExpandSelect : true}),
25940
+ oNewRoot,
25863
25941
  oRoot,
25864
25942
  oTable,
25865
25943
  sView = '\
@@ -25883,6 +25961,16 @@ sap.ui.define([
25883
25961
  </t:Table>',
25884
25962
  that = this;
25885
25963
 
25964
+ // 9 Aleph (created later)
25965
+ // 0 Alpha
25966
+ // 1 Beta (initially collapsed)
25967
+ // 1.1 Gamma
25968
+ // 1.2 Zeta
25969
+ // 2 Kappa
25970
+ // 3 Lambda
25971
+ // 4 Mu
25972
+ // 5 Xi
25973
+ // ...
25886
25974
  this.expectRequest({
25887
25975
  batchNo : 1,
25888
25976
  url : "EMPLOYEES/$count"
@@ -25959,7 +26047,7 @@ sap.ui.define([
25959
26047
  assert.strictEqual(oListBinding.getDownloadUrl(), sTeaBusi + "EMPLOYEES"
25960
26048
  + "?$apply=orderby(AGE%20desc)"
25961
26049
  + "/com.sap.vocabularies.Hierarchy.v1.TopLevels(HierarchyNodes=$root/EMPLOYEES"
25962
- + ",HierarchyQualifier='OrgChart',NodeProperty='ID',Levels=999)"
26050
+ + ",HierarchyQualifier='OrgChart',NodeProperty='ID')"
25963
26051
  + "&$select=AGE,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name",
25964
26052
  "JIRA: CPOUI5ODATAV4-1920, CPOUI5ODATAV4-2275");
25965
26053
 
@@ -26026,7 +26114,6 @@ sap.ui.define([
26026
26114
  }) // 204 No Content
26027
26115
  .expectRequest({
26028
26116
  batchNo : 3,
26029
- method : "GET",
26030
26117
  url : "EMPLOYEES?$select=AGE,ID,Name&$filter=ID eq '2'"
26031
26118
  }, {
26032
26119
  value : [{
@@ -26197,6 +26284,136 @@ sap.ui.define([
26197
26284
  ["", "", "", "", "", ""],
26198
26285
  ["", "", "", "", "", ""]
26199
26286
  ]);
26287
+
26288
+ that.expectRequest({
26289
+ batchNo : 6,
26290
+ method : "POST",
26291
+ url : "EMPLOYEES",
26292
+ payload : {
26293
+ // not needed: "EMPLOYEE_2_MANAGER@odata.bind" : null,
26294
+ AGE : 99,
26295
+ Name : "Aleph"
26296
+ }
26297
+ }, {
26298
+ AGE : 199, // side effect
26299
+ ID : "9",
26300
+ MANAGER_ID : null,
26301
+ Name : "Aleph: ℵ" // side effect
26302
+ })
26303
+ .expectRequest({
26304
+ batchNo : 6,
26305
+ url : "EMPLOYEES?$select=AGE,ID&$filter=ID eq '0'"
26306
+ }, {
26307
+ value : [{
26308
+ AGE : 160,
26309
+ ID : "0"
26310
+ }]
26311
+ });
26312
+
26313
+ // code under test (JIRA: CPOUI5ODATAV4-2355)
26314
+ oNewRoot = oListBinding.create({AGE : 99, Name : "Aleph"}, /*bSkipRefresh*/true);
26315
+
26316
+ assert.strictEqual(oNewRoot.getIndex(), 0);
26317
+
26318
+ return Promise.all([
26319
+ oNewRoot.created(),
26320
+ // code under test
26321
+ oListBinding.getHeaderContext().requestSideEffects(["AGE"]),
26322
+ that.waitForChanges(assert, "create new root, side effect: AGE for all rows")
26323
+ ]);
26324
+ }).then(function () {
26325
+ checkTable("new root created, after side effect: AGE for all rows", assert, oTable, [
26326
+ "/EMPLOYEES('9')",
26327
+ "/EMPLOYEES('0')"
26328
+ ], [
26329
+ [undefined, 1, "9", "", "Aleph: ℵ", 199],
26330
+ [false, 1, "0", "", "Alpha", 160],
26331
+ ["", "", "", "", "", ""]
26332
+ ]);
26333
+ assert.strictEqual(oNewRoot.isTransient(), false, "created persisted");
26334
+
26335
+ that.expectRequest("EMPLOYEES?$apply=orderby(AGE desc)"
26336
+ + "/com.sap.vocabularies.Hierarchy.v1.TopLevels(HierarchyNodes=$root/EMPLOYEES"
26337
+ + ",HierarchyQualifier='OrgChart',NodeProperty='ID',Levels=2)"
26338
+ + "&$select=AGE,DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
26339
+ + "&$filter=not (ID eq '9')&$skip=1&$top=1", {
26340
+ value : [{
26341
+ AGE : 155,
26342
+ DescendantCount : "0", // Edm.Int64
26343
+ DistanceFromRoot : "1", // Edm.Int64
26344
+ DrillState : "collapsed", // Note: overridden by client-side tree state!
26345
+ ID : "1",
26346
+ MANAGER_ID : "0",
26347
+ Name : "Beta"
26348
+ }]
26349
+ });
26350
+
26351
+ // code under test
26352
+ oRoot.expand();
26353
+
26354
+ return that.waitForChanges(assert, "expand 0 (Alpha) again");
26355
+ }).then(function () {
26356
+ checkTable("after expand 0 (Alpha) again", assert, oTable, [
26357
+ "/EMPLOYEES('9')",
26358
+ "/EMPLOYEES('0')",
26359
+ "/EMPLOYEES('1')"
26360
+ ], [
26361
+ [undefined, 1, "9", "", "Aleph: ℵ", 199],
26362
+ [true, 1, "0", "", "Alpha", 160],
26363
+ [true, 2, "1", "0", "Beta", 155]
26364
+ ], 9);
26365
+
26366
+ that.expectRequest("EMPLOYEES"
26367
+ + "?$apply=descendants($root/EMPLOYEES,OrgChart,ID,filter(ID eq '1'),1)"
26368
+ + "/orderby(AGE desc)"
26369
+ + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$skip=0&$top=2", {
26370
+ value : [{
26371
+ AGE : 141,
26372
+ DrillState : "collapsed",
26373
+ ID : "1.1",
26374
+ MANAGER_ID : "1",
26375
+ Name : "Gamma"
26376
+ }, {
26377
+ AGE : 142,
26378
+ DrillState : "collapsed",
26379
+ ID : "1.2",
26380
+ MANAGER_ID : "1",
26381
+ Name : "Zeta"
26382
+ }]
26383
+ })
26384
+ .expectRequest("EMPLOYEES?$apply=orderby(AGE desc)"
26385
+ + "/com.sap.vocabularies.Hierarchy.v1.TopLevels(HierarchyNodes=$root/EMPLOYEES"
26386
+ + ",HierarchyQualifier='OrgChart',NodeProperty='ID',Levels=2)"
26387
+ + "&$select=AGE,DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
26388
+ + "&$filter=not (ID eq '9')&$skip=2&$top=1", {
26389
+ value : [{
26390
+ AGE : 166,
26391
+ DescendantCount : "0",
26392
+ DistanceFromRoot : "1",
26393
+ DrillState : "leaf",
26394
+ ID : "2",
26395
+ MANAGER_ID : "0",
26396
+ Name : "Kappa: κ"
26397
+ }]
26398
+ });
26399
+
26400
+ // code under test
26401
+ oTable.setFirstVisibleRow(3);
26402
+
26403
+ return that.waitForChanges(assert, "scroll down");
26404
+ }).then(function () {
26405
+ checkTable("after scroll down", assert, oTable, [
26406
+ "/EMPLOYEES('9')",
26407
+ "/EMPLOYEES('0')",
26408
+ "/EMPLOYEES('1')",
26409
+ "/EMPLOYEES('1.1')",
26410
+ "/EMPLOYEES('1.2')",
26411
+ "/EMPLOYEES('2')"
26412
+ ], [
26413
+ [false, 3, "1.1", "1", "Gamma", 141],
26414
+ [false, 3, "1.2", "1", "Zeta", 142],
26415
+ [undefined, 2, "2", "0", "Kappa: κ", 166]
26416
+ ], 9);
26200
26417
  });
26201
26418
  });
26202
26419
 
@@ -26437,7 +26654,7 @@ sap.ui.define([
26437
26654
  + ",filter(AGE%20ge%200%20and%20(Is_Manager))/search(covfefe),keep%20start)"
26438
26655
  + "/orderby(AGE%20desc)"
26439
26656
  + "/com.sap.vocabularies.Hierarchy.v1.TopLevels(HierarchyNodes=$root/EMPLOYEES"
26440
- + ",HierarchyQualifier='OrgChart',NodeProperty='ID',Levels=999)"
26657
+ + ",HierarchyQualifier='OrgChart',NodeProperty='ID')"
26441
26658
  + "&$select=DistanceFromRoot,DrillState,ID",
26442
26659
  "JIRA: CPOUI5ODATAV4-1920, CPOUI5ODATAV4-2275");
26443
26660
 
@@ -26476,10 +26693,24 @@ sap.ui.define([
26476
26693
  // initially expanded nodes 1 (Beta) and 0 (Alpha). See that an additional root node becomes
26477
26694
  // visible!
26478
26695
  // JIRA: CPOUI5ODATAV4-1743
26696
+ //
26697
+ // Create new child and cancel immediately via deletion (JIRA: CPOUI5ODATAV4-2359)
26698
+ //
26699
+ // While the root node 0 (Alpha) is still collapsed, a new root (Beth) is created; a side effect
26700
+ // for all rows turns spliced nodes into placeholders, then 0 (Alpha) is expanded again to check
26701
+ // that placeholders still cause proper requests w.r.t. indices.
26702
+ // JIRA: CPOUI5ODATAV4-2355
26703
+ //
26704
+ // A new child (Gimel) for 0 (Alpha) is created, then 0 (Alpha) is collapsed again to check
26705
+ // that the internal "limited descendant count" has been updated correctly. Finally, 0 (Alpha)
26706
+ // is expanded again to check that internal "index" handling is correct.
26707
+ // JIRA: CPOUI5ODATAV4-2359
26479
26708
  QUnit.test("Recursive Hierarchy: collapse nested initially expanded nodes", function (assert) {
26480
26709
  var oAlpha,
26481
26710
  oBeta,
26482
26711
  oModel = this.createTeaBusiModel({autoExpandSelect : true}),
26712
+ oNewChild,
26713
+ oNewRoot,
26483
26714
  oTable,
26484
26715
  sView = '\
26485
26716
  <t:Table id="table" rows="{path : \'/EMPLOYEES\',\
@@ -26498,7 +26729,9 @@ sap.ui.define([
26498
26729
  </t:Table>',
26499
26730
  that = this;
26500
26731
 
26732
+ // B Beth (created later)
26501
26733
  // 0 Alpha
26734
+ // C Gimel (created later)
26502
26735
  // 1 Beta
26503
26736
  // 1.1 Gamma
26504
26737
  // 1.2 Zeta
@@ -26579,6 +26812,13 @@ sap.ui.define([
26579
26812
  [undefined, 2, "2", "0", "Kappa", 56]
26580
26813
  ], 11);
26581
26814
 
26815
+ // code under test (JIRA: CPOUI5ODATAV4-2359)
26816
+ const oLostChild = oAlpha.getBinding().create({
26817
+ "@$ui5.node.parent" : oAlpha,
26818
+ Name : "n/a"
26819
+ }, /*bSkipRefresh*/true);
26820
+ const oDeletePromise = oLostChild.delete();
26821
+
26582
26822
  that.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
26583
26823
  + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
26584
26824
  + ",NodeProperty='ID',Levels=3)"
@@ -26605,7 +26845,11 @@ sap.ui.define([
26605
26845
 
26606
26846
  oBeta.collapse();
26607
26847
 
26608
- return that.waitForChanges(assert, "collapse 1 (Beta)");
26848
+ return Promise.all([
26849
+ checkCanceled(assert, oLostChild.created()),
26850
+ oDeletePromise,
26851
+ that.waitForChanges(assert, "collapse 1 (Beta)")
26852
+ ]);
26609
26853
  }).then(function () {
26610
26854
  checkTable("after collapse 1 (Beta) ", assert, oTable, [
26611
26855
  "/EMPLOYEES('0')",
@@ -26641,7 +26885,7 @@ sap.ui.define([
26641
26885
 
26642
26886
  return that.waitForChanges(assert, "collapse 0 (Alpha)");
26643
26887
  }).then(function () {
26644
- checkTable("after collapse 0 (Alpha) ", assert, oTable, [
26888
+ checkTable("after collapse 0 (Alpha)", assert, oTable, [
26645
26889
  "/EMPLOYEES('0')",
26646
26890
  "/EMPLOYEES('9')"
26647
26891
  ], [
@@ -26651,6 +26895,233 @@ sap.ui.define([
26651
26895
  ["", "", "", "", "", ""],
26652
26896
  ["", "", "", "", "", ""]
26653
26897
  ], 2);
26898
+ const oAleph = oTable.getRows()[1].getBindingContext();
26899
+
26900
+ // code under test
26901
+ assert.strictEqual(oAlpha.isAncestorOf(oAleph), false, "JIRA: CPOUI5ODATAV4-2337");
26902
+ assert.strictEqual(oAleph.isAncestorOf(oAlpha), false, "JIRA: CPOUI5ODATAV4-2337");
26903
+
26904
+ that.expectRequest({
26905
+ method : "POST",
26906
+ url : "EMPLOYEES",
26907
+ payload : {
26908
+ // not needed: "EMPLOYEE_2_MANAGER@odata.bind" : null,
26909
+ Name : "Beth"
26910
+ }
26911
+ }, {
26912
+ AGE : 70,
26913
+ ID : "B",
26914
+ MANAGER_ID : null,
26915
+ Name : "Beth, not Beta" // side effect
26916
+ });
26917
+
26918
+ // code under test (JIRA: CPOUI5ODATAV4-2355)
26919
+ oNewRoot = oAlpha.getBinding().create({Name : "Beth"}, /*bSkipRefresh*/true);
26920
+
26921
+ assert.strictEqual(oNewRoot.getIndex(), 0);
26922
+
26923
+ return Promise.all([
26924
+ oNewRoot.created(),
26925
+ that.waitForChanges(assert, "create new root")
26926
+ ]);
26927
+ }).then(function () {
26928
+ checkTable("after create new root", assert, oTable, [
26929
+ "/EMPLOYEES('B')",
26930
+ "/EMPLOYEES('0')",
26931
+ "/EMPLOYEES('9')"
26932
+ ], [
26933
+ [undefined, 1, "B", "", "Beth, not Beta", 70],
26934
+ [false, 1, "0", "", "Alpha", 60],
26935
+ [undefined, 1, "9", "", "Aleph", 69],
26936
+ ["", "", "", "", "", ""],
26937
+ ["", "", "", "", "", ""]
26938
+ ]);
26939
+ assert.strictEqual(oNewRoot.isTransient(), false, "created persisted");
26940
+
26941
+ that.expectRequest("EMPLOYEES?$select=AGE,ID"
26942
+ + "&$filter=ID eq 'B' or ID eq '0' or ID eq '9'&$top=3", {
26943
+ value : [{
26944
+ AGE : 170,
26945
+ ID : "B" // Beth
26946
+ }, {
26947
+ AGE : 160,
26948
+ ID : "0" // Alpha
26949
+ }, {
26950
+ AGE : 169,
26951
+ ID : "9" // Aleph
26952
+ }]
26953
+ });
26954
+
26955
+ return Promise.all([
26956
+ // code under test
26957
+ oAlpha.getBinding().getHeaderContext().requestSideEffects(["AGE"]),
26958
+ that.waitForChanges(assert, "side effect: AGE for all rows")
26959
+ ]);
26960
+ }).then(function () {
26961
+ checkTable("after side effect: AGE for all rows", assert, oTable, [
26962
+ "/EMPLOYEES('B')",
26963
+ "/EMPLOYEES('0')",
26964
+ "/EMPLOYEES('9')"
26965
+ ], [
26966
+ [undefined, 1, "B", "", "Beth, not Beta", 170],
26967
+ [false, 1, "0", "", "Alpha", 160],
26968
+ [undefined, 1, "9", "", "Aleph", 169],
26969
+ ["", "", "", "", "", ""],
26970
+ ["", "", "", "", "", ""]
26971
+ ]);
26972
+
26973
+ that.expectRequest({batchNo : 6,
26974
+ url : "EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
26975
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
26976
+ + ",NodeProperty='ID',Levels=3)"
26977
+ + "&$select=AGE,DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
26978
+ + "&$filter=not (ID eq 'B')&$skip=1&$top=1"}, {
26979
+ value : [{
26980
+ AGE : 155,
26981
+ DescendantCount : "2",
26982
+ DistanceFromRoot : "1",
26983
+ DrillState : "expanded", // Note: overridden by client-side tree state!
26984
+ ID : "1",
26985
+ MANAGER_ID : "0",
26986
+ Name : "Beta"
26987
+ }]
26988
+ })
26989
+ .expectRequest({batchNo : 6,
26990
+ url : "EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
26991
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
26992
+ + ",NodeProperty='ID',Levels=3)"
26993
+ + "&$select=AGE,DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
26994
+ + "&$filter=not (ID eq 'B')&$skip=4&$top=2"}, {
26995
+ value : [{
26996
+ AGE : 156,
26997
+ DescendantCount : "0",
26998
+ DistanceFromRoot : "1",
26999
+ DrillState : "leaf",
27000
+ ID : "2",
27001
+ MANAGER_ID : "0",
27002
+ Name : "Kappa"
27003
+ }, {
27004
+ AGE : 157,
27005
+ DescendantCount : "0",
27006
+ DistanceFromRoot : "1",
27007
+ DrillState : "leaf",
27008
+ ID : "3",
27009
+ MANAGER_ID : "0",
27010
+ Name : "Lambda"
27011
+ }]
27012
+ });
27013
+
27014
+ // code under test
27015
+ oAlpha.expand();
27016
+
27017
+ return that.waitForChanges(assert, "expand 0 (Alpha)");
27018
+ }).then(function () {
27019
+ checkTable("after expand 0 (Alpha)", assert, oTable, [
27020
+ "/EMPLOYEES('B')",
27021
+ "/EMPLOYEES('0')",
27022
+ "/EMPLOYEES('1')",
27023
+ "/EMPLOYEES('2')",
27024
+ "/EMPLOYEES('3')",
27025
+ "/EMPLOYEES('9')"
27026
+ ], [
27027
+ [undefined, 1, "B", "", "Beth, not Beta", 170],
27028
+ [true, 1, "0", "", "Alpha", 160],
27029
+ [false, 2, "1", "0", "Beta", 155],
27030
+ [undefined, 2, "2", "0", "Kappa", 156],
27031
+ [undefined, 2, "3", "0", "Lambda", 157]
27032
+ ], 10);
27033
+
27034
+ that.expectRequest({
27035
+ method : "POST",
27036
+ url : "EMPLOYEES",
27037
+ payload : {
27038
+ "EMPLOYEE_2_MANAGER@odata.bind" : "EMPLOYEES('0')",
27039
+ Name : "gIMEL"
27040
+ }
27041
+ }, {
27042
+ AGE : 180,
27043
+ ID : "C",
27044
+ MANAGER_ID : "0", // side effect
27045
+ Name : "Gimel" // side effect
27046
+ });
27047
+
27048
+ // code under test (JIRA: CPOUI5ODATAV4-2359)
27049
+ oNewChild = oAlpha.getBinding().create({
27050
+ "@$ui5.node.parent" : oAlpha,
27051
+ Name : "gIMEL"
27052
+ }, /*bSkipRefresh*/true);
27053
+
27054
+ assert.strictEqual(oNewChild.getIndex(), 2);
27055
+ assert.strictEqual(oNewChild.getProperty("@$ui5.node.level"), 2);
27056
+ assert.deepEqual(oNewChild.getObject(), {
27057
+ "@$ui5.context.isTransient" : true,
27058
+ "@$ui5.node.level" : 2,
27059
+ // "@$ui5.node.parent" : oAlpha, // removed by #create
27060
+ Name : "gIMEL"
27061
+ });
27062
+
27063
+ return Promise.all([
27064
+ oNewChild.created(),
27065
+ that.waitForChanges(assert, "create new child beneath 0 (Alpha)")
27066
+ ]);
27067
+ }).then(function () {
27068
+ checkTable("after create new child beneath 0 (Alpha)", assert, oTable, [
27069
+ "/EMPLOYEES('B')",
27070
+ "/EMPLOYEES('0')",
27071
+ "/EMPLOYEES('C')",
27072
+ "/EMPLOYEES('1')",
27073
+ "/EMPLOYEES('2')",
27074
+ "/EMPLOYEES('3')",
27075
+ "/EMPLOYEES('9')"
27076
+ ], [
27077
+ [undefined, 1, "B", "", "Beth, not Beta", 170],
27078
+ [true, 1, "0", "", "Alpha", 160],
27079
+ [undefined, 2, "C", "0", "Gimel", 180],
27080
+ [false, 2, "1", "0", "Beta", 155],
27081
+ [undefined, 2, "2", "0", "Kappa", 156]
27082
+ ], 11);
27083
+ assert.strictEqual(oNewChild.isTransient(), false, "created persisted");
27084
+
27085
+ // code under test
27086
+ oAlpha.collapse();
27087
+
27088
+ return that.waitForChanges(assert, "collapse 0 (Alpha) again");
27089
+ }).then(function () {
27090
+ checkTable("after collapse 0 (Alpha) again", assert, oTable, [
27091
+ "/EMPLOYEES('B')",
27092
+ "/EMPLOYEES('0')",
27093
+ "/EMPLOYEES('9')"
27094
+ ], [
27095
+ [undefined, 1, "B", "", "Beth, not Beta", 170],
27096
+ [false, 1, "0", "", "Alpha", 160],
27097
+ [undefined, 1, "9", "", "Aleph", 169],
27098
+ ["", "", "", "", "", ""],
27099
+ ["", "", "", "", "", ""]
27100
+ ]);
27101
+
27102
+ // code under test
27103
+ oAlpha.expand();
27104
+
27105
+ return that.waitForChanges(assert, "expand 0 (Alpha) again");
27106
+ }).then(function () {
27107
+ checkTable("after create new child beneath 0 (Alpha)", assert, oTable, [
27108
+ "/EMPLOYEES('B')",
27109
+ "/EMPLOYEES('0')",
27110
+ "/EMPLOYEES('C')",
27111
+ "/EMPLOYEES('1')",
27112
+ "/EMPLOYEES('2')",
27113
+ "/EMPLOYEES('3')",
27114
+ "/EMPLOYEES('9')"
27115
+ ], [
27116
+ [undefined, 1, "B", "", "Beth, not Beta", 170],
27117
+ [true, 1, "0", "", "Alpha", 160],
27118
+ [undefined, 2, "C", "0", "Gimel", 180],
27119
+ [false, 2, "1", "0", "Beta", 155],
27120
+ [undefined, 2, "2", "0", "Kappa", 156]
27121
+ ], 11);
27122
+ assert.strictEqual(oNewChild.getBinding().getCurrentContexts()[2], oNewChild,
27123
+ "still the same");
27124
+ assert.strictEqual(oNewChild.isTransient(), false, "created persisted");
26654
27125
  });
26655
27126
  });
26656
27127
 
@@ -27710,8 +28181,8 @@ sap.ui.define([
27710
28181
  });
27711
28182
 
27712
28183
  //*********************************************************************************************
27713
- // Scenario: Deferred delete and reinsert of a top-level node in a recursive hierarchy. Only
27714
- // one node, so that the parent would have to become a leaf if there were one.
28184
+ // Scenario: Delete a top-level node in a recursive hierarchy. The binding has only one node, so
28185
+ // that the parent would have to become a leaf if there was one.
27715
28186
  // JIRA: CPOUI5ODATAV4-2224
27716
28187
  QUnit.test("Recursive Hierarchy: delete top-level", async function (assert) {
27717
28188
  const oModel = this.createTeaBusiModel({autoExpandSelect : true});
@@ -27726,9 +28197,9 @@ sap.ui.define([
27726
28197
  <Text id="name" text="{Name}"/>
27727
28198
  </Table>`;
27728
28199
 
27729
- this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels"
27730
- + "(HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart',NodeProperty='ID'"
27731
- + ",Levels=1)"
28200
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28201
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28202
+ + ",NodeProperty='ID',Levels=1)"
27732
28203
  + "&$select=DrillState,ID,Name&$count=true&$skip=0&$top=100", {
27733
28204
  "@odata.count" : "1",
27734
28205
  value : [{
@@ -27741,42 +28212,27 @@ sap.ui.define([
27741
28212
  await this.createView(assert, sView, oModel);
27742
28213
 
27743
28214
  const oTable = this.oView.byId("table");
27744
- const oAlpha = oTable.getItems()[0].getBindingContext();
27745
- // code under test
27746
- const oDeletePromise = oAlpha.delete("doNotSubmit");
27747
-
27748
- await resolveLater(); // no observable changes
27749
-
27750
- checkTable("after delete", assert, oTable, [], [], 0);
27751
-
27752
- this.expectCanceledError("Failed to delete /EMPLOYEES('0')",
27753
- "Request canceled: DELETE EMPLOYEES('0'); group: doNotSubmit")
27754
- .expectChange("name", ["Alpha"]);
27755
-
27756
- // code under test
27757
- oAlpha.resetChanges();
28215
+ this.expectRequest("DELETE EMPLOYEES('0')");
27758
28216
 
27759
28217
  await Promise.all([
27760
- checkCanceled(assert, oDeletePromise),
27761
- this.waitForChanges(assert, "cancel delete")
28218
+ oTable.getItems()[0].getBindingContext().delete(), // code under test
28219
+ this.waitForChanges(assert, "delete")
27762
28220
  ]);
27763
28221
 
27764
- checkTable("after reinsert", assert, oTable, ["/EMPLOYEES('0')"], [
27765
- ["0", "Alpha"]
27766
- ], 1);
28222
+ checkTable("after delete", assert, oTable, [], [], 0);
27767
28223
  });
27768
28224
 
27769
28225
  //*********************************************************************************************
27770
- // Scenario: Deferred delete of Gamma, a leaf in a recursive hierarchy which is not the only
27771
- // child of its parent. Before the delete ensure that there are two invisible elements (Delta,
27772
- // Epsilon). See that Gamma is deleted on the UI immediately. Request side effects so that
27773
- // Epsilon is removed again. Scroll down to see that Epsilon and Zeta are requested correctly.
27774
- // Cancel the delete and check that Gamma is restored correcty. Scroll down to the end to see
27775
- // that Eta and Theta are requested correctly.
28226
+ // Scenario: Delete Gamma, a leaf in a recursive hierarchy which is not the only child of its
28227
+ // parent. Before the delete ensure that there are two invisible elements (Delta, Epsilon).
28228
+ // Request side effects so that Epsilon is removed again. Scroll down to see that Epsilon and
28229
+ // Zeta are requested correctly. Scroll down to the end to see that Eta and Theta are requested
28230
+ // correctly.
27776
28231
  // ("Pi" is attached to a name when it is read a second time.)
27777
28232
  // JIRA: CPOUI5ODATAV4-2224
28233
+ // JIRA: CPOUI5ODATAV4-2345
27778
28234
  QUnit.test("Recursive Hierarchy: delete second leaf", function (assert) {
27779
- var oDeletePromise, oGamma, oTable;
28235
+ var oTable;
27780
28236
 
27781
28237
  const oModel = this.createTeaBusiModel({autoExpandSelect : true});
27782
28238
  const sView = `
@@ -27798,13 +28254,13 @@ sap.ui.define([
27798
28254
  // 1 Beta
27799
28255
  // 2 Gamma (deleted)
27800
28256
  // 3 Delta (read via expand, comes into view due to delete)
27801
- // 4 Epsilon (exists hidden during delete, then dropped and read again via paging)
28257
+ // 4 Epsilon (exists hidden when deleting, then dropped and read again via paging)
27802
28258
  // 5 Zeta (read via paging after delete)
27803
- // 6 Eta (read via paging after reset)
28259
+ // 6 Eta (read via paging after delete)
27804
28260
  // 7 Theta
27805
- this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels"
27806
- + "(HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart',NodeProperty='ID'"
27807
- + ",Levels=1)"
28261
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28262
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28263
+ + ",NodeProperty='ID',Levels=1)"
27808
28264
  + "&$select=DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=3", {
27809
28265
  "@odata.count" : "2",
27810
28266
  value : [{
@@ -27888,13 +28344,13 @@ sap.ui.define([
27888
28344
  [undefined, 2, "2", "0", "Gamma"]
27889
28345
  ], 8);
27890
28346
 
27891
- that.expectChange("name", [,, "Delta"]);
27892
-
27893
- oGamma = oTable.getRows()[2].getBindingContext();
27894
- // code under test
27895
- oDeletePromise = oGamma.delete("doNotSubmit");
28347
+ that.expectRequest("DELETE EMPLOYEES('2')")
28348
+ .expectChange("name", [,, "Delta"]);
27896
28349
 
27897
- return that.waitForChanges(assert, "delete");
28350
+ return Promise.all([
28351
+ oTable.getRows()[2].getBindingContext().delete(), // code under test
28352
+ that.waitForChanges(assert, "delete")
28353
+ ]);
27898
28354
  }).then(function () {
27899
28355
  checkTable("after delete", assert, oTable, [
27900
28356
  "/EMPLOYEES('0')",
@@ -27925,14 +28381,13 @@ sap.ui.define([
27925
28381
 
27926
28382
  return Promise.all([
27927
28383
  // code under test
27928
- oGamma.getBinding().getHeaderContext().requestSideEffects(["Name"]),
28384
+ oTable.getBinding("rows").getHeaderContext().requestSideEffects(["Name"]),
27929
28385
  that.waitForChanges(assert, "side effects")
27930
28386
  ]);
27931
28387
  }).then(function () {
27932
28388
  that.expectRequest("EMPLOYEES"
27933
28389
  + "?$apply=descendants($root/EMPLOYEES,OrgChart,ID,filter(ID eq '0'),1)"
27934
- + "&$select=DrillState,ID,MANAGER_ID,Name&$filter=not (ID eq '2')"
27935
- + "&$skip=2&$top=2", {
28390
+ + "&$select=DrillState,ID,MANAGER_ID,Name&$skip=2&$top=2", {
27936
28391
  "@odata.count" : "5",
27937
28392
  value : [{
27938
28393
  DrillState : "leaf",
@@ -27951,45 +28406,11 @@ sap.ui.define([
27951
28406
  // code under test
27952
28407
  oTable.setFirstVisibleRow(2);
27953
28408
 
27954
- return that.waitForChanges(assert, "scroll while deleted");
27955
- }).then(function () {
27956
- checkTable("after scroll while deleted", assert, oTable, [
27957
- "/EMPLOYEES('0')",
27958
- "/EMPLOYEES('1')",
27959
- "/EMPLOYEES('3')",
27960
- "/EMPLOYEES('4')",
27961
- "/EMPLOYEES('5')"
27962
- ], [
27963
- [undefined, 2, "3", "0", "Delta Pi"],
27964
- [undefined, 2, "4", "0", "Epsilon Pi"],
27965
- [false, 2, "5", "0", "Zeta"]
27966
- ], 7);
27967
-
27968
- that.expectCanceledError("Failed to delete /EMPLOYEES('2')",
27969
- "Request canceled: DELETE EMPLOYEES('2'); group: doNotSubmit")
27970
- .expectChange("name", [,, "Gamma", "Delta Pi", "Epsilon Pi", "Zeta"]);
27971
-
27972
- // code under test
27973
- oGamma.resetChanges();
27974
-
27975
- return checkCanceled(assert, oDeletePromise);
28409
+ return that.waitForChanges(assert, "scroll after delete");
27976
28410
  }).then(function () {
27977
- checkTable("after reset", assert, oTable, [
27978
- "/EMPLOYEES('0')",
27979
- "/EMPLOYEES('1')",
27980
- "/EMPLOYEES('2')",
27981
- "/EMPLOYEES('3')",
27982
- "/EMPLOYEES('4')",
27983
- "/EMPLOYEES('5')"
27984
- ], [
27985
- [undefined, 2, "2", "0", "Gamma"],
27986
- [undefined, 2, "3", "0", "Delta Pi"],
27987
- [undefined, 2, "4", "0", "Epsilon Pi"]
27988
- ], 8);
27989
-
27990
28411
  that.expectRequest("EMPLOYEES"
27991
28412
  + "?$apply=descendants($root/EMPLOYEES,OrgChart,ID,filter(ID eq '0'),1)"
27992
- + "&$select=DrillState,ID,MANAGER_ID,Name&$skip=5&$top=1", {
28413
+ + "&$select=DrillState,ID,MANAGER_ID,Name&$skip=4&$top=1", {
27993
28414
  value : [{
27994
28415
  DrillState : "collapsed",
27995
28416
  ID : "6",
@@ -28008,17 +28429,16 @@ sap.ui.define([
28008
28429
  Name : "Theta Pi"
28009
28430
  }]
28010
28431
  })
28011
- .expectChange("name", [,,,,,, "Eta", "Theta Pi"]);
28432
+ .expectChange("name", [,,,, "Zeta", "Eta", "Theta Pi"]);
28012
28433
 
28013
28434
  // code under test
28014
- oTable.setFirstVisibleRow(5);
28435
+ oTable.setFirstVisibleRow(4);
28015
28436
 
28016
28437
  return that.waitForChanges(assert, "scroll to bottom");
28017
28438
  }).then(function () {
28018
28439
  checkTable("after scroll to bottom", assert, oTable, [
28019
28440
  "/EMPLOYEES('0')",
28020
28441
  "/EMPLOYEES('1')",
28021
- "/EMPLOYEES('2')",
28022
28442
  "/EMPLOYEES('3')",
28023
28443
  "/EMPLOYEES('4')",
28024
28444
  "/EMPLOYEES('5')",
@@ -28028,24 +28448,24 @@ sap.ui.define([
28028
28448
  [false, 2, "5", "0", "Zeta"],
28029
28449
  [false, 2, "6", "0", "Eta"],
28030
28450
  [false, 1, "7", "", "Theta Pi"]
28031
- ], 8);
28451
+ ], 7);
28032
28452
  });
28033
28453
  });
28034
28454
 
28035
28455
  //*********************************************************************************************
28036
- // Scenario: Deferred delete of a non-leaf node with loaded children in a recursive hierarchy
28037
- // which is the only child of its parent. Two variants: delete while collapsed and while
28038
- // expanded.
28456
+ // Scenario: Delete a non-leaf node with loaded children in a recursive hierarchy which is the
28457
+ // only child of its parent. Two variants: delete while collapsed and while expanded.
28039
28458
  // * Expand Alpha and Beta.
28040
28459
  // * Collapse Beta (in variant 1).
28041
- // * Delete Beta in an API group. See that Alpha becomes a leaf.
28042
- // * Cancel the delete.
28043
- // * Expand Beta without a further request (in variant 1).
28044
- // * See that Alpha is expanded, and that Gamma is shown again.
28460
+ // * Delete Beta and let the request fail. See that it is expanded again in variant 2.
28461
+ // * Delete Beta again. See that Alpha becomes a leaf.
28045
28462
  // JIRA: CPOUI5ODATAV4-2224
28463
+ // JIRA: CPOUI5ODATAV4-2345
28046
28464
  [false, true].forEach(function (bExpanded) {
28047
28465
  const sState = bExpanded ? "expanded" : "collapsed";
28048
28466
  QUnit.test(`Recursive Hierarchy: delete single ${sState} child`, async function (assert) {
28467
+ var oTable;
28468
+
28049
28469
  const oModel = this.createTeaBusiModel({autoExpandSelect : true});
28050
28470
  const sView = `
28051
28471
  <Table id="table" items="{path : '/EMPLOYEES',
@@ -28061,9 +28481,35 @@ sap.ui.define([
28061
28481
  <Text id="name" text="{Name}"/>
28062
28482
  </Table>`;
28063
28483
 
28484
+ function expectTable(sTitle, bExpanded) {
28485
+ if (bExpanded) {
28486
+ checkTable(sTitle, assert, oTable, [
28487
+ "/EMPLOYEES('0')",
28488
+ "/EMPLOYEES('1')",
28489
+ "/EMPLOYEES('2')",
28490
+ "/EMPLOYEES('3')"
28491
+ ], [
28492
+ [true, 1, "0", "", "Alpha"],
28493
+ [true, 2, "1", "0", "Beta"],
28494
+ [false, 3, "2", "1", "Gamma"],
28495
+ [false, 1, "3", "", "Delta"]
28496
+ ], 4);
28497
+ } else {
28498
+ checkTable(sTitle, assert, oTable, [
28499
+ "/EMPLOYEES('0')",
28500
+ "/EMPLOYEES('1')",
28501
+ "/EMPLOYEES('3')"
28502
+ ], [
28503
+ [true, 1, "0", "", "Alpha"],
28504
+ [false, 2, "1", "0", "Beta"],
28505
+ [false, 1, "3", "", "Delta"]
28506
+ ], 3);
28507
+ }
28508
+ }
28509
+
28064
28510
  // 0 Alpha
28065
28511
  // 1 Beta (deleted while Gamma is loaded)
28066
- // 2 Gamma (must not get lost)
28512
+ // 2 Gamma (allows expanding Beta)
28067
28513
  // 3 Delta (only helps with the eventing)
28068
28514
  this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels"
28069
28515
  + "(HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart',NodeProperty='ID'"
@@ -28101,7 +28547,7 @@ sap.ui.define([
28101
28547
  .expectChange("expanded", [true,, false])
28102
28548
  .expectChange("name", [, "Beta", "Delta"]);
28103
28549
 
28104
- const oTable = this.oView.byId("table");
28550
+ oTable = this.oView.byId("table");
28105
28551
  oTable.getItems()[0].getBindingContext().expand();
28106
28552
 
28107
28553
  await this.waitForChanges(assert, "expand Alpha");
@@ -28125,20 +28571,11 @@ sap.ui.define([
28125
28571
 
28126
28572
  await this.waitForChanges(assert, "expand Beta");
28127
28573
 
28128
- checkTable("after expand", assert, oTable, [
28129
- "/EMPLOYEES('0')",
28130
- "/EMPLOYEES('1')",
28131
- "/EMPLOYEES('2')",
28132
- "/EMPLOYEES('3')"
28133
- ], [
28134
- [true, 1, "0", "", "Alpha"],
28135
- [true, 2, "1", "0", "Beta"],
28136
- [false, 3, "2", "1", "Gamma"],
28137
- [false, 1, "3", "", "Delta"]
28138
- ], 4);
28574
+ expectTable("after expand", true);
28139
28575
 
28140
28576
  if (bExpanded) {
28141
- this.expectChange("expanded", [, false]); // Beta is collapsed before being deleted
28577
+ this.expectChange("expanded", [, false]) // Beta is collapsed before being deleted
28578
+ .expectChange("expanded", [, true]); // ...and expanded again after the error
28142
28579
  } else {
28143
28580
  this.expectChange("expanded", [, false])
28144
28581
  .expectChange("name", [,, "Delta"]);
@@ -28147,24 +28584,38 @@ sap.ui.define([
28147
28584
 
28148
28585
  await this.waitForChanges(assert, "collapse Beta");
28149
28586
 
28150
- checkTable("after collapse", assert, oTable, [
28151
- "/EMPLOYEES('0')",
28152
- "/EMPLOYEES('1')",
28153
- "/EMPLOYEES('3')"
28154
- ], [
28155
- [true, 1, "0", "", "Alpha"],
28156
- [false, 2, "1", "0", "Beta"],
28157
- [false, 1, "3", "", "Delta"]
28158
- ], 3);
28587
+ expectTable("after collapse", false);
28159
28588
  }
28160
28589
 
28161
- this.expectChange("expanded", [undefined]) // Alpha is now a leaf
28162
- .expectChange("name", [, "Delta"]);
28590
+ this.oLogMock.expects("error").withArgs("Failed to delete /EMPLOYEES('1')");
28591
+ this.expectRequest("DELETE EMPLOYEES('1')", createErrorInsideBatch())
28592
+ .expectMessages([{
28593
+ code : "CODE",
28594
+ message : "Request intentionally failed",
28595
+ persistent : true,
28596
+ technical : true,
28597
+ type : "Error"
28598
+ }]);
28163
28599
 
28164
- // code under test
28165
- const oDeletePromise = oBeta.delete("doNotSubmit");
28600
+ await Promise.all([
28601
+ // code under test
28602
+ oBeta.delete().then(mustFail(assert), function (_oError) {}),
28603
+ this.waitForChanges(assert, "failing to delete Beta")
28604
+ ]);
28605
+
28606
+ expectTable("after failed delete", bExpanded);
28607
+
28608
+ if (bExpanded) {
28609
+ this.expectChange("expanded", [, false]); // Beta is collapsed before being deleted
28610
+ }
28611
+ this.expectRequest("DELETE EMPLOYEES('1')")
28612
+ .expectChange("expanded", [undefined]) // Alpha is now a leaf
28613
+ .expectChange("name", [, "Delta"]);
28166
28614
 
28167
- await this.waitForChanges(assert, "delete Beta");
28615
+ await Promise.all([
28616
+ oBeta.delete(), // code under test
28617
+ this.waitForChanges(assert, "delete Beta")
28618
+ ]);
28168
28619
 
28169
28620
  checkTable("after delete", assert, oTable, [
28170
28621
  "/EMPLOYEES('0')",
@@ -28173,47 +28624,176 @@ sap.ui.define([
28173
28624
  [undefined, 1, "0", "", "Alpha"], // now a leaf
28174
28625
  [false, 1, "3", "", "Delta"]
28175
28626
  ], 2);
28627
+ });
28628
+ });
28176
28629
 
28177
- this.expectCanceledError("Failed to delete /EMPLOYEES('1')",
28178
- "Request canceled: DELETE EMPLOYEES('1'); group: doNotSubmit");
28179
- if (bExpanded) {
28180
- // Alpha is expanded again, Beta is expanded after being restored
28181
- this.expectChange("expanded", [true, true, false, false])
28182
- .expectChange("name", [, "Beta", "Gamma", "Delta"]);
28183
- } else {
28184
- this.expectChange("expanded", [true,, false]) // Alpha is expanded again
28185
- .expectChange("name", [, "Beta", "Delta"]);
28186
- }
28630
+ //*********************************************************************************************
28631
+ // Scenario: Delete multiple nodes in a recursive hierarchy
28632
+ // JIRA: CPOUI5ODATAV4-2302
28633
+ QUnit.test("Recursive Hierarchy: delete multiple nodes", async function (assert) {
28634
+ const oModel = this.createTeaBusiModel({autoExpandSelect : true});
28635
+ const sView = `
28636
+ <Table id="table" items="{path : '/EMPLOYEES',
28637
+ parameters : {
28638
+ $$aggregation : {
28639
+ hierarchyQualifier : 'OrgChart'
28640
+ }
28641
+ }}">
28642
+ <Text text="{= %{@$ui5.node.isExpanded} }"/>
28643
+ <Text text="{= %{@$ui5.node.level} }"/>
28644
+ <Text text="{ID}"/>
28645
+ <Text text="{MANAGER_ID}"/>
28646
+ <Text text="{Name}"/>
28647
+ </Table>`;
28187
28648
 
28188
- // code under test
28189
- oBeta.resetChanges();
28649
+ // 0 Alpha
28650
+ // 1 Beta (deleted)
28651
+ // 2 Gamma (deleted)
28652
+ // 3 Delta
28653
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels"
28654
+ + "(HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart',NodeProperty='ID'"
28655
+ + ",Levels=1)"
28656
+ + "&$select=DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=100", {
28657
+ "@odata.count" : "1",
28658
+ value : [{
28659
+ DrillState : "collapsed",
28660
+ ID : "0",
28661
+ MANAGER_ID : null,
28662
+ Name : "Alpha"
28663
+ }]
28664
+ });
28665
+
28666
+ await this.createView(assert, sView, oModel);
28667
+
28668
+ this.expectRequest("EMPLOYEES"
28669
+ + "?$apply=descendants($root/EMPLOYEES,OrgChart,ID,filter(ID eq '0'),1)"
28670
+ + "&$select=DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=100", {
28671
+ "@odata.count" : "3",
28672
+ value : [{
28673
+ DrillState : "leaf",
28674
+ ID : "1",
28675
+ MANAGER_ID : "0",
28676
+ Name : "Beta"
28677
+ }, {
28678
+ DrillState : "leaf",
28679
+ ID : "2",
28680
+ MANAGER_ID : "0",
28681
+ Name : "Gamma"
28682
+ }, {
28683
+ DrillState : "leaf",
28684
+ ID : "3",
28685
+ MANAGER_ID : "0",
28686
+ Name : "Delta"
28687
+ }]
28688
+ });
28689
+
28690
+ const oTable = this.oView.byId("table");
28691
+ oTable.getItems()[0].getBindingContext().expand();
28692
+
28693
+ await this.waitForChanges(assert, "expand Alpha");
28694
+
28695
+ checkTable("after expand Alpha", assert, oTable, [
28696
+ "/EMPLOYEES('0')",
28697
+ "/EMPLOYEES('1')",
28698
+ "/EMPLOYEES('2')",
28699
+ "/EMPLOYEES('3')"
28700
+ ], [
28701
+ [true, 1, "0", "", "Alpha"],
28702
+ [undefined, 2, "1", "0", "Beta"],
28703
+ [undefined, 2, "2", "0", "Gamma"],
28704
+ [undefined, 2, "3", "0", "Delta"]
28705
+ ]);
28706
+
28707
+ this.expectRequest("DELETE EMPLOYEES('1')")
28708
+ .expectRequest("DELETE EMPLOYEES('2')");
28190
28709
 
28191
28710
  await Promise.all([
28192
- checkCanceled(assert, oDeletePromise),
28193
- this.waitForChanges(assert, "cancel")
28711
+ // code under test
28712
+ oTable.getItems()[1].getBindingContext().delete(),
28713
+ oTable.getItems()[2].getBindingContext().delete(),
28714
+ this.waitForChanges(assert, "delete Beta and Gamma")
28194
28715
  ]);
28195
28716
 
28196
- if (!bExpanded) {
28197
- checkTable("after reset", assert, oTable, [
28198
- "/EMPLOYEES('0')",
28199
- "/EMPLOYEES('1')",
28200
- "/EMPLOYEES('3')"
28201
- ], [
28202
- [true, 1, "0", "", "Alpha"], // expanded again
28203
- [false, 2, "1", "0", "Beta"],
28204
- [false, 1, "3", "", "Delta"]
28205
- ], 3);
28717
+ checkTable("after delete", assert, oTable, [
28718
+ "/EMPLOYEES('0')",
28719
+ "/EMPLOYEES('3')"
28720
+ ], [
28721
+ [true, 1, "0", "", "Alpha"],
28722
+ [undefined, 2, "3", "0", "Delta"]
28723
+ ]);
28724
+ });
28206
28725
 
28207
- this.expectChange("expanded", [, true, , false])
28208
- .expectChange("name", [, , "Gamma", "Delta"]);
28726
+ //*********************************************************************************************
28727
+ // Scenario: Delete a non-leaf node with descendants loaded partially via expandTo in a
28728
+ // recursive hierarchy which is the only child of its parent.
28729
+ //
28730
+ // JIRA: CPOUI5ODATAV4-2302
28731
+ QUnit.test("Recursive Hierarchy: delete & expandTo, one ancestor", async function (assert) {
28732
+ const oModel = this.createTeaBusiModel({autoExpandSelect : true});
28733
+ const sView = `
28734
+ <t:Table id="table" rows="{path : '/EMPLOYEES',
28735
+ parameters : {
28736
+ $$aggregation : {
28737
+ expandTo : 4,
28738
+ hierarchyQualifier : 'OrgChart'
28739
+ }
28740
+ }}" threshold="0" visibleRowCount="4">
28741
+ <Text id="expanded" text="{= %{@$ui5.node.isExpanded} }"/>
28742
+ <Text text="{= %{@$ui5.node.level} }"/>
28743
+ <Text text="{ID}"/>
28744
+ <Text text="{MANAGER_ID}"/>
28745
+ <Text id="name" text="{Name}"/>
28746
+ </t:Table>`;
28209
28747
 
28210
- // code under test
28211
- oBeta.expand();
28748
+ // 0 Alpha
28749
+ // 1 Beta (deleted)
28750
+ // 2 Gamma (visible during the delete)
28751
+ // 3 Delta (visible during the delete)
28752
+ // 4 Epsilon (invisible during the delete)
28753
+ // 5 Zeta (only helps with the eventing)
28754
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28755
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28756
+ + ",NodeProperty='ID',Levels=4)"
28757
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
28758
+ + "&$count=true&$skip=0&$top=4", {
28759
+ "@odata.count" : "6",
28760
+ value : [{
28761
+ DescendantCount : "4",
28762
+ DistanceFromRoot : "0",
28763
+ DrillState : "expanded",
28764
+ ID : "0",
28765
+ MANAGER_ID : null,
28766
+ Name : "Alpha"
28767
+ }, {
28768
+ DescendantCount : "3",
28769
+ DistanceFromRoot : "1",
28770
+ DrillState : "expanded",
28771
+ ID : "1",
28772
+ MANAGER_ID : "0",
28773
+ Name : "Beta"
28774
+ }, {
28775
+ DescendantCount : "1",
28776
+ DistanceFromRoot : "2",
28777
+ DrillState : "expanded",
28778
+ ID : "2",
28779
+ MANAGER_ID : "1",
28780
+ Name : "Gamma"
28781
+ }, {
28782
+ DescendantCount : "0",
28783
+ DistanceFromRoot : "3",
28784
+ DrillState : "collapsed",
28785
+ ID : "3",
28786
+ MANAGER_ID : "2",
28787
+ Name : "Delta"
28788
+ }]
28789
+ })
28790
+ .expectChange("expanded", [true, true, true, false])
28791
+ .expectChange("name", ["Alpha", "Beta", "Gamma", "Delta"]);
28212
28792
 
28213
- await this.waitForChanges(assert, "expand again");
28214
- }
28793
+ await this.createView(assert, sView, oModel);
28215
28794
 
28216
- checkTable("finally", assert, oTable, [
28795
+ const oTable = this.oView.byId("table");
28796
+ checkTable("initially", assert, oTable, [
28217
28797
  "/EMPLOYEES('0')",
28218
28798
  "/EMPLOYEES('1')",
28219
28799
  "/EMPLOYEES('2')",
@@ -28221,161 +28801,655 @@ sap.ui.define([
28221
28801
  ], [
28222
28802
  [true, 1, "0", "", "Alpha"],
28223
28803
  [true, 2, "1", "0", "Beta"],
28224
- [false, 3, "2", "1", "Gamma"],
28225
- [false, 1, "3", "", "Delta"]
28226
- ], 4);
28804
+ [true, 3, "2", "1", "Gamma"],
28805
+ [false, 4, "3", "2", "Delta"]
28806
+ ], 6);
28807
+
28808
+ this.expectChange("expanded", [, false]) // Beta is collapsed before being deleted
28809
+ .expectRequest("DELETE EMPLOYEES('1')")
28810
+ .expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28811
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28812
+ + ",NodeProperty='ID',Levels=4)"
28813
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
28814
+ + "&$skip=1&$top=1", {
28815
+ value : [{
28816
+ DescendantCount : "0",
28817
+ DistanceFromRoot : "0",
28818
+ DrillState : "leaf",
28819
+ ID : "5",
28820
+ MANAGER_ID : null,
28821
+ Name : "Zeta"
28822
+ }]
28823
+ })
28824
+ .expectChange("expanded", [undefined]) // Alpha is now a leaf
28825
+ .expectChange("name", [, "Zeta"]);
28826
+
28827
+ await Promise.all([
28828
+ oTable.getRows()[1].getBindingContext().delete(), // code under test
28829
+ this.waitForChanges(assert, "delete Beta")
28830
+ ]);
28831
+
28832
+ checkTable("finally", assert, oTable, [
28833
+ "/EMPLOYEES('0')",
28834
+ "/EMPLOYEES('5')"
28835
+ ], [
28836
+ [undefined, 1, "0", "", "Alpha"], // now a leaf
28837
+ [undefined, 1, "5", "", "Zeta"]
28838
+ ]);
28227
28839
  });
28228
- });
28229
28840
 
28230
28841
  //*********************************************************************************************
28231
- // Scenario: Deferred delete in a recursive hierarchy. Before reinserting the node, delete two
28232
- // other nodes, so that both the parent's position and the deleted node's position within the
28233
- // level cache change.
28234
- // * Expand Beta
28235
- // * Deferred delete Delta
28236
- // * Delete Gamma (Beta becomes leaf) and Alpha
28237
- // * Reinsert Delta (Beta becomes expanded again)
28238
- // JIRA: CPOUI5ODATAV4-2224
28239
- QUnit.test("Recursive Hierarchy: delete and change reinsertion index", async function (assert) {
28842
+ // Scenario: Delete node Epsilon in a recursive hierarchy, preloaded via expandTo. The parent
28843
+ // node Gamma has not been loaded yet, but the grandparent Beta has. Load Gamma and Delta,
28844
+ // delete Delta, so that two ancestors need to be adjusted. In the end, collapse Beta to see
28845
+ // that it was adjusted correctly.
28846
+ // JIRA: CPOUI5ODATAV4-2302
28847
+ QUnit.test("Recursive Hierarchy: delete & expandTo, two ancestors", async function (assert) {
28240
28848
  const oModel = this.createTeaBusiModel({autoExpandSelect : true});
28241
28849
  const sView = `
28242
- <Table id="table" items="{path : '/EMPLOYEES',
28850
+ <t:Table id="table" rows="{path : '/EMPLOYEES',
28243
28851
  parameters : {
28244
28852
  $$aggregation : {
28853
+ expandTo : 3,
28245
28854
  hierarchyQualifier : 'OrgChart'
28246
28855
  }
28247
- }}">
28856
+ }}" threshold="0" visibleRowCount="2">
28248
28857
  <Text id="expanded" text="{= %{@$ui5.node.isExpanded} }"/>
28249
28858
  <Text text="{= %{@$ui5.node.level} }"/>
28250
28859
  <Text text="{ID}"/>
28251
28860
  <Text text="{MANAGER_ID}"/>
28252
28861
  <Text id="name" text="{Name}"/>
28253
- </Table>`;
28862
+ </t:Table>`;
28254
28863
 
28255
- // 0 Alpha (delete to change Beta's index)
28256
- // 1 Beta
28257
- // 2 Gamma (delete to change Delta's index in the level cache and make Beta a leaf)
28258
- // 3 Delta (deferred delete and reinsert)
28259
- // 4 Epsilon
28260
- this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels"
28261
- + "(HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart',NodeProperty='ID'"
28262
- + ",Levels=1)"
28263
- + "&$select=DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=100", {
28264
- "@odata.count" : "3",
28864
+ // 0 Alpha
28865
+ // 1 Beta (grandparent)
28866
+ // 2 Gamma (invisible during the 1st delete)
28867
+ // 3 Delta (invisible during the 1st delete, deleted later)
28868
+ // 4 Epsilon (deleted)
28869
+ // 5 Zeta
28870
+ // 6 Eta
28871
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28872
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28873
+ + ",NodeProperty='ID',Levels=3)"
28874
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
28875
+ + "&$count=true&$skip=0&$top=2", {
28876
+ "@odata.count" : "7",
28265
28877
  value : [{
28266
- DrillState : "collapsed",
28878
+ DescendantCount : "0",
28879
+ DistanceFromRoot : "0",
28880
+ DrillState : "leaf",
28267
28881
  ID : "0",
28268
28882
  MANAGER_ID : null,
28269
28883
  Name : "Alpha"
28270
28884
  }, {
28271
- DrillState : "collapsed",
28885
+ DescendantCount : "3",
28886
+ DistanceFromRoot : "0",
28887
+ DrillState : "expanded",
28272
28888
  ID : "1",
28273
28889
  MANAGER_ID : null,
28274
28890
  Name : "Beta"
28275
- }, {
28891
+ }]
28892
+ })
28893
+ .expectChange("expanded", [undefined, true])
28894
+ .expectChange("name", ["Alpha", "Beta"]);
28895
+
28896
+ await this.createView(assert, sView, oModel);
28897
+
28898
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28899
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28900
+ + ",NodeProperty='ID'" + ",Levels=3)"
28901
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
28902
+ + "&$skip=4&$top=2", {
28903
+ value : [{
28904
+ DescendantCount : "0",
28905
+ DistanceFromRoot : "2",
28276
28906
  DrillState : "collapsed",
28277
28907
  ID : "4",
28278
- MANAGER_ID : null,
28908
+ MANAGER_ID : "3",
28279
28909
  Name : "Epsilon"
28910
+ }, {
28911
+ DescendantCount : "1",
28912
+ DistanceFromRoot : "0",
28913
+ DrillState : "expanded",
28914
+ ID : "5",
28915
+ MANAGER_ID : null,
28916
+ Name : "Zeta"
28280
28917
  }]
28281
28918
  })
28282
- .expectChange("expanded", [false, false, false])
28283
- .expectChange("name", ["Alpha", "Beta", "Epsilon"]);
28919
+ .expectChange("expanded", [,,,, false, true])
28920
+ .expectChange("name", [,,,, "Epsilon", "Zeta"]);
28284
28921
 
28285
- await this.createView(assert, sView, oModel);
28922
+ const oTable = this.oView.byId("table");
28923
+ oTable.setFirstVisibleRow(4);
28286
28924
 
28287
- this.expectRequest("EMPLOYEES"
28288
- + "?$apply=descendants($root/EMPLOYEES,OrgChart,ID,filter(ID eq '1'),1)"
28289
- + "&$select=DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=100", {
28290
- "@odata.count" : "2",
28925
+ await this.waitForChanges(assert, "scroll down creating gap");
28926
+
28927
+ checkTable("before delete", assert, oTable, [
28928
+ "/EMPLOYEES('0')",
28929
+ "/EMPLOYEES('1')",
28930
+ "/EMPLOYEES('4')",
28931
+ "/EMPLOYEES('5')"
28932
+ ], [
28933
+ [false, 3, "4", "3", "Epsilon"],
28934
+ [true, 1, "5", "", "Zeta"]
28935
+ ], 7);
28936
+
28937
+ this.expectRequest("DELETE EMPLOYEES('4')")
28938
+ .expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28939
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28940
+ + ",NodeProperty='ID',Levels=3)"
28941
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
28942
+ + "&$skip=5&$top=1", {
28291
28943
  value : [{
28292
- DrillState : "collapsed",
28944
+ DescendantCount : "0",
28945
+ DistanceFromRoot : "1",
28946
+ DrillState : "leaf",
28947
+ ID : "6",
28948
+ MANAGER_ID : "5",
28949
+ Name : "Eta"
28950
+ }]
28951
+ })
28952
+ .expectChange("expanded", [,,,, true])
28953
+ .expectChange("name", [,,,, "Zeta", "Eta"]);
28954
+
28955
+ await Promise.all([
28956
+ // code under test
28957
+ oTable.getRows()[0].getBindingContext().delete(),
28958
+ this.waitForChanges(assert, "1st delete")
28959
+ ]);
28960
+
28961
+ checkTable("after 1st delete", assert, oTable, [
28962
+ "/EMPLOYEES('0')",
28963
+ "/EMPLOYEES('1')",
28964
+ "/EMPLOYEES('5')",
28965
+ "/EMPLOYEES('6')"
28966
+ ], [
28967
+ [true, 1, "5", "", "Zeta"],
28968
+ [undefined, 2, "6", "5", "Eta"]
28969
+ ], 6);
28970
+
28971
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28972
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28973
+ + ",NodeProperty='ID',Levels=3)"
28974
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
28975
+ + "&$skip=2&$top=2", {
28976
+ value : [
28977
+ {
28978
+ DescendantCount : "1",
28979
+ DistanceFromRoot : "1",
28980
+ DrillState : "expanded",
28981
+ ID : "2",
28982
+ MANAGER_ID : "1",
28983
+ Name : "Gamma"
28984
+ }, {
28985
+ DescendantCount : "0",
28986
+ DistanceFromRoot : "2",
28987
+ DrillState : "collapsed", // "leaf" is similar (nothing to do)
28988
+ ID : "3",
28989
+ MANAGER_ID : "2",
28990
+ Name : "Delta"
28991
+ }
28992
+ ]
28993
+ })
28994
+ .expectChange("expanded", [, , true, false])
28995
+ .expectChange("name", [, , "Gamma", "Delta"]);
28996
+
28997
+ oTable.setFirstVisibleRow(2);
28998
+
28999
+ await this.waitForChanges(assert, "scroll up closing gap");
29000
+
29001
+ checkTable("before 2nd delete", assert, oTable, [
29002
+ "/EMPLOYEES('0')",
29003
+ "/EMPLOYEES('1')",
29004
+ "/EMPLOYEES('2')",
29005
+ "/EMPLOYEES('3')",
29006
+ "/EMPLOYEES('5')",
29007
+ "/EMPLOYEES('6')"
29008
+ ], [
29009
+ [true, 2, "2", "1", "Gamma"],
29010
+ [false, 3, "3", "2", "Delta"]
29011
+ ]);
29012
+
29013
+ this.expectRequest("DELETE EMPLOYEES('3')")
29014
+ .expectChange("expanded", [,, undefined, true]) // Gamma becomes leaf
29015
+ .expectChange("name", [,,, "Zeta"]);
29016
+
29017
+ await Promise.all([
29018
+ oTable.getRows()[1].getBindingContext().delete(), // code under test
29019
+ this.waitForChanges(assert, "2nd delete")
29020
+ ]);
29021
+
29022
+ checkTable("after 2nd delete", assert, oTable, [
29023
+ "/EMPLOYEES('0')",
29024
+ "/EMPLOYEES('1')",
29025
+ "/EMPLOYEES('2')",
29026
+ "/EMPLOYEES('5')",
29027
+ "/EMPLOYEES('6')"
29028
+ ], [
29029
+ [undefined, 2, "2", "1", "Gamma"],
29030
+ [true, 1, "5", "", "Zeta"]
29031
+ ]);
29032
+
29033
+ this.expectChange("expanded", [, true, undefined])
29034
+ .expectChange("name", [, "Beta", "Gamma"]);
29035
+
29036
+ oTable.setFirstVisibleRow(1);
29037
+
29038
+ await this.waitForChanges(assert, "make Beta visible");
29039
+
29040
+ checkTable("after making Beta visible", assert, oTable, [
29041
+ "/EMPLOYEES('0')",
29042
+ "/EMPLOYEES('1')",
29043
+ "/EMPLOYEES('2')",
29044
+ "/EMPLOYEES('5')",
29045
+ "/EMPLOYEES('6')"
29046
+ ], [
29047
+ [true, 1, "1", "", "Beta"],
29048
+ [undefined, 2, "2", "1", "Gamma"]
29049
+ ]);
29050
+
29051
+ this.expectChange("expanded", [, false, true])
29052
+ .expectChange("name", [,, "Zeta"]);
29053
+
29054
+ oTable.getRows()[0].getBindingContext().collapse();
29055
+
29056
+ await this.waitForChanges(assert, "collapse Beta");
29057
+
29058
+ checkTable("after collapse", assert, oTable, [
29059
+ "/EMPLOYEES('0')",
29060
+ "/EMPLOYEES('1')",
29061
+ "/EMPLOYEES('5')",
29062
+ "/EMPLOYEES('6')"
29063
+ ], [
29064
+ [false, 1, "1", "", "Beta"],
29065
+ [true, 1, "5", "", "Zeta"]
29066
+ ]);
29067
+ });
29068
+
29069
+ //*********************************************************************************************
29070
+ // Scenario: Delete node Epsilon, preloaded via expandTo and expanded manually. Its parent Delta
29071
+ // is not loaded yet. Collapse Beta to see that it is not accidentally adjusted instead of
29072
+ // Delta. Collapse Alpha to see that it has been adjusted.
29073
+ // JIRA: CPOUI5ODATAV4-2302
29074
+ QUnit.test("Recursive Hierarchy: delete & expandTo, invisible parent", async function (assert) {
29075
+ const oModel = this.createTeaBusiModel({autoExpandSelect : true});
29076
+ const sView = `
29077
+ <t:Table id="table" rows="{path : '/EMPLOYEES',
29078
+ parameters : {
29079
+ $$aggregation : {
29080
+ expandTo : 3,
29081
+ hierarchyQualifier : 'OrgChart'
29082
+ }
29083
+ }}" threshold="0" visibleRowCount="3">
29084
+ <Text id="expanded" text="{= %{@$ui5.node.isExpanded} }"/>
29085
+ <Text text="{= %{@$ui5.node.level} }"/>
29086
+ <Text text="{ID}"/>
29087
+ <Text text="{MANAGER_ID}"/>
29088
+ <Text id="name" text="{Name}"/>
29089
+ </t:Table>`;
29090
+
29091
+ // 0 Alpha
29092
+ // 1 Beta
29093
+ // 2 Gamma
29094
+ // 3 Delta (invisible parent)
29095
+ // 4 Epsilon (deleted)
29096
+ // 4.1 Omega
29097
+ // 5 Zeta
29098
+ // 6 Theta
29099
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
29100
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
29101
+ + ",NodeProperty='ID',Levels=3)"
29102
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
29103
+ + "&$count=true&$skip=0&$top=3", {
29104
+ "@odata.count" : "7",
29105
+ value : [{
29106
+ DescendantCount : "4",
29107
+ DistanceFromRoot : "0",
29108
+ DrillState : "expanded",
29109
+ ID : "0",
29110
+ MANAGER_ID : null,
29111
+ Name : "Alpha"
29112
+ }, {
29113
+ DescendantCount : "1",
29114
+ DistanceFromRoot : "1",
29115
+ DrillState : "expanded",
29116
+ ID : "1",
29117
+ MANAGER_ID : "0",
29118
+ Name : "Beta"
29119
+ }, {
29120
+ DescendantCount : "0",
29121
+ DistanceFromRoot : "2",
29122
+ DrillState : "leaf",
28293
29123
  ID : "2",
28294
29124
  MANAGER_ID : "1",
28295
29125
  Name : "Gamma"
29126
+ }]
29127
+ })
29128
+ .expectChange("expanded", [true, true, undefined])
29129
+ .expectChange("name", ["Alpha", "Beta", "Gamma"]);
29130
+
29131
+ await this.createView(assert, sView, oModel);
29132
+
29133
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
29134
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart',"
29135
+ + "NodeProperty='ID',Levels=3)"
29136
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
29137
+ + "&$skip=4&$top=3", {
29138
+ value : [{
29139
+ DescendantCount : "0",
29140
+ DistanceFromRoot : "2",
29141
+ DrillState : "collapsed",
29142
+ ID : "4",
29143
+ MANAGER_ID : "3",
29144
+ Name : "Epsilon"
29145
+ }, {
29146
+ DescendantCount : "0",
29147
+ DistanceFromRoot : "0",
29148
+ DrillState : "leaf",
29149
+ ID : "5",
29150
+ MANAGER_ID : null,
29151
+ Name : "Zeta"
28296
29152
  }, {
29153
+ DescendantCount : "0",
29154
+ DistanceFromRoot : "0",
28297
29155
  DrillState : "leaf",
28298
- ID : "3",
28299
- MANAGER_ID : "1",
28300
- Name : "Delta"
29156
+ ID : "6",
29157
+ MANAGER_ID : null,
29158
+ Name : "Theta"
28301
29159
  }]
28302
29160
  })
28303
- .expectChange("expanded", [, true,, undefined, false])
28304
- .expectChange("name", [,, "Gamma", "Delta", "Epsilon"]);
29161
+ .expectChange("expanded", [,,,, false])
29162
+ .expectChange("name", [,,,, "Epsilon", "Zeta", "Theta"]);
28305
29163
 
28306
29164
  const oTable = this.oView.byId("table");
28307
- oTable.getItems()[1].getBindingContext().expand();
29165
+ oTable.setFirstVisibleRow(4);
28308
29166
 
28309
- await this.waitForChanges(assert, "expand Beta");
29167
+ await this.waitForChanges(assert, "scroll down creating gap");
28310
29168
 
28311
- checkTable("before delete", assert, oTable, [
29169
+ this.expectRequest("EMPLOYEES?$apply=descendants($root/EMPLOYEES,OrgChart,ID"
29170
+ + ",filter(ID eq '4'),1)&$select=DrillState,ID,MANAGER_ID,Name&$count=true"
29171
+ + "&$skip=0&$top=3", {
29172
+ "@odata.count" : "1",
29173
+ value : [{
29174
+ DrillState : "leaf",
29175
+ ID : "4.1",
29176
+ MANAGER_ID : "4",
29177
+ Name : "Omega"
29178
+ }]
29179
+ })
29180
+ .expectChange("expanded", [,,,, true])
29181
+ .expectChange("name", [,,,,, "Omega", "Zeta"]);
29182
+
29183
+ await Promise.all([
29184
+ oTable.getRows()[0].getBindingContext().expand(),
29185
+ this.waitForChanges(assert, "expand Epsilon")
29186
+ ]);
29187
+
29188
+ checkTable("after expanding Epsilon", assert, oTable, [
29189
+ "/EMPLOYEES('0')",
29190
+ "/EMPLOYEES('1')",
29191
+ "/EMPLOYEES('2')",
29192
+ "/EMPLOYEES('4')",
29193
+ "/EMPLOYEES('4.1')",
29194
+ "/EMPLOYEES('5')",
29195
+ "/EMPLOYEES('6')"
29196
+ ], [
29197
+ [true, 3, "4", "3", "Epsilon"],
29198
+ [undefined, 4, "4.1", "4", "Omega"],
29199
+ [undefined, 1, "5", "", "Zeta"]
29200
+ ], 8);
29201
+
29202
+ this.expectRequest("DELETE EMPLOYEES('4')")
29203
+ // Note: the table sets the first visible row to 3 due to the length
29204
+ .expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
29205
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
29206
+ + ",NodeProperty='ID',Levels=3)"
29207
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
29208
+ + "&$skip=3&$top=1", {
29209
+ value : [{
29210
+ DescendantCount : "0",
29211
+ DistanceFromRoot : "1",
29212
+ DrillState : "leaf",
29213
+ ID : "3",
29214
+ MANAGER_ID : "0",
29215
+ Name : "Delta"
29216
+ }]
29217
+ })
29218
+ .expectChange("expanded", [,,,, false]) // Epsilon is collapsed before the delete
29219
+ .expectChange("name", [,,, "Delta", "Zeta", "Theta"]);
29220
+
29221
+ await Promise.all([
29222
+ oTable.getRows()[0].getBindingContext().delete(),
29223
+ this.waitForChanges(assert, "delete")
29224
+ ]);
29225
+
29226
+ checkTable("after delete", assert, oTable, [
28312
29227
  "/EMPLOYEES('0')",
28313
29228
  "/EMPLOYEES('1')",
28314
29229
  "/EMPLOYEES('2')",
28315
29230
  "/EMPLOYEES('3')",
28316
- "/EMPLOYEES('4')"
29231
+ "/EMPLOYEES('5')",
29232
+ "/EMPLOYEES('6')"
28317
29233
  ], [
28318
- [false, 1, "0", "", "Alpha"],
28319
- [true, 1, "1", "", "Beta"],
28320
- [false, 2, "2", "1", "Gamma"],
28321
- [undefined, 2, "3", "1", "Delta"],
28322
- [false, 1, "4", "", "Epsilon"]
28323
- ], 5);
29234
+ [undefined, "2", "3", "0", "Delta"],
29235
+ [undefined, "1", "5", "", "Zeta"],
29236
+ [undefined, "1", "6", "", "Theta"]
29237
+ ]);
28324
29238
 
28325
- this.expectChange("expanded", [,,, false])
28326
- .expectChange("name", [,,, "Epsilon"]);
29239
+ this.expectChange("expanded", [true, true])
29240
+ .expectChange("name", ["Alpha", "Beta", "Gamma"]);
28327
29241
 
28328
- // code under test
28329
- const oDelta = oTable.getItems()[3].getBindingContext();
28330
- const oDeleteDeltaPromise = oDelta.delete("doNotSubmit");
29242
+ oTable.setFirstVisibleRow(0);
28331
29243
 
28332
- await this.waitForChanges(assert, "delete Delta");
29244
+ await this.waitForChanges(assert, "make Alpha & Beta visible");
28333
29245
 
28334
- this.expectChange("expanded", [undefined, false])
28335
- .expectChange("name", ["Beta", "Epsilon"])
28336
- .expectRequest("DELETE EMPLOYEES('2')")
28337
- .expectRequest("DELETE EMPLOYEES('0')");
29246
+ this.expectChange("expanded", [, false])
29247
+ .expectChange("name", [,, "Delta"]);
28338
29248
 
28339
- // code under test
28340
- const oDeleteGammaPromise = oTable.getItems()[2].getBindingContext().delete();
28341
- const oDeleteAlphaPromise = oTable.getItems()[0].getBindingContext().delete();
29249
+ oTable.getRows()[1].getBindingContext().collapse();
28342
29250
 
28343
- await Promise.all([
28344
- oDeleteGammaPromise,
28345
- oDeleteAlphaPromise,
28346
- this.waitForChanges(assert, "delete Gamma and Alpha")
29251
+ await this.waitForChanges(assert, "collapse Beta");
29252
+
29253
+ checkTable("after collapsing Beta", assert, oTable, [
29254
+ "/EMPLOYEES('0')",
29255
+ "/EMPLOYEES('1')",
29256
+ "/EMPLOYEES('3')",
29257
+ "/EMPLOYEES('5')",
29258
+ "/EMPLOYEES('6')"
29259
+ ], [
29260
+ [true, 1, "0", "", "Alpha"],
29261
+ [false, 2, "1", "0", "Beta"],
29262
+ [undefined, 2, "3", "0", "Delta"]
28347
29263
  ]);
28348
29264
 
28349
- checkTable("after delete", assert, oTable, [
29265
+ this.expectChange("expanded", [false, undefined])
29266
+ .expectChange("name", [, "Zeta", "Theta"]);
29267
+
29268
+ oTable.getRows()[0].getBindingContext().collapse();
29269
+
29270
+ await this.waitForChanges(assert, "collapse Alpha");
29271
+
29272
+ checkTable("after collapsing Alpha", assert, oTable, [
29273
+ "/EMPLOYEES('0')",
29274
+ "/EMPLOYEES('5')",
29275
+ "/EMPLOYEES('6')"
29276
+ ], [
29277
+ [false, 1, "0", "", "Alpha"],
29278
+ [undefined, 1, "5", "", "Zeta"],
29279
+ [undefined, 1, "6", "", "Theta"]
29280
+ ]);
29281
+ });
29282
+
29283
+ //*********************************************************************************************
29284
+ // Scenario: Delete node Beta, preloaded via expandTo. Its parent is not loaded yet, hence no
29285
+ // ancestor can be found at all. Before the deletion collapse Gamma manually. See that after the
29286
+ // deletion Epsilon is requested correctly when Gamma is expanded again.
29287
+ // JIRA: CPOUI5ODATAV4-2302
29288
+ QUnit.test("Recursive Hierarchy: delete & expandTo, parent missing", async function (assert) {
29289
+ const oModel = this.createTeaBusiModel({autoExpandSelect : true});
29290
+ const sView = `
29291
+ <t:Table firstVisibleRow="1" id="table" rows="{path : '/EMPLOYEES',
29292
+ parameters : {
29293
+ $$aggregation : {
29294
+ expandTo : 3,
29295
+ hierarchyQualifier : 'OrgChart'
29296
+ }
29297
+ }}" threshold="0" visibleRowCount="3">
29298
+ <Text id="expanded" text="{= %{@$ui5.node.isExpanded} }"/>
29299
+ <Text text="{= %{@$ui5.node.level} }"/>
29300
+ <Text text="{ID}"/>
29301
+ <Text text="{MANAGER_ID}"/>
29302
+ <Text id="name" text="{Name}"/>
29303
+ </t:Table>`;
29304
+
29305
+ // 0 Alpha (invisible parent)
29306
+ // 1 Beta (delete)
29307
+ // 2 Gamma (manually collapsed before delete)
29308
+ // 3 Delta (loaded before the delete)
29309
+ // 4 Epsilon (loaded when re-expanding after the delete)
29310
+ // 5 Zeta
29311
+ // 6 Eta
29312
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
29313
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
29314
+ + ",NodeProperty='ID',Levels=3)"
29315
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
29316
+ + "&$count=true&$skip=1&$top=3", {
29317
+ "@odata.count" : "7",
29318
+ value : [{
29319
+ DescendantCount : "0",
29320
+ DistanceFromRoot : "1",
29321
+ DrillState : "leaf",
29322
+ ID : "1",
29323
+ MANAGER_ID : "0",
29324
+ Name : "Beta"
29325
+ }, {
29326
+ DescendantCount : "2",
29327
+ DistanceFromRoot : "1",
29328
+ DrillState : "expanded",
29329
+ ID : "2",
29330
+ MANAGER_ID : "0",
29331
+ Name : "Gamma"
29332
+ }, {
29333
+ DescendantCount : "0",
29334
+ DistanceFromRoot : "2",
29335
+ DrillState : "leaf",
29336
+ ID : "3",
29337
+ MANAGER_ID : "2",
29338
+ Name : "Delta"
29339
+ }]
29340
+ })
29341
+ .expectChange("expanded", [, undefined, true, undefined])
29342
+ .expectChange("name", [, "Beta", "Gamma", "Delta"]);
29343
+
29344
+ await this.createView(assert, sView, oModel);
29345
+
29346
+ const oTable = this.oView.byId("table");
29347
+ checkTable("initial", assert, oTable, [
28350
29348
  "/EMPLOYEES('1')",
28351
- "/EMPLOYEES('4')"
29349
+ "/EMPLOYEES('2')",
29350
+ "/EMPLOYEES('3')"
28352
29351
  ], [
28353
- [undefined, 1, "1", "", "Beta"],
28354
- [false, 1, "4", "", "Epsilon"]
28355
- ], 2);
29352
+ [undefined, 2, "1", "0", "Beta"],
29353
+ [true, 2, "2", "0", "Gamma"],
29354
+ [undefined, 3, "3", "2", "Delta"]
29355
+ ], 7);
29356
+
29357
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
29358
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
29359
+ + ",NodeProperty='ID',Levels=3)"
29360
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
29361
+ + "&$skip=5&$top=1", {
29362
+ value : [{
29363
+ DescendantCount : "0",
29364
+ DistanceFromRoot : "1",
29365
+ DrillState : "leaf",
29366
+ ID : "5",
29367
+ MANAGER_ID : "0",
29368
+ Name : "Zeta"
29369
+ }]
29370
+ })
29371
+ .expectChange("expanded", [,, false])
29372
+ .expectChange("name", [,,, "Zeta"]);
28356
29373
 
28357
- this.expectCanceledError("Failed to delete /EMPLOYEES('3')",
28358
- "Request canceled: DELETE EMPLOYEES('3'); group: doNotSubmit")
28359
- .expectChange("expanded", [true, undefined, false])
28360
- .expectChange("name", [, "Delta", "Epsilon"]);
29374
+ oTable.getRows()[1].getBindingContext().collapse();
28361
29375
 
28362
- // code under test
28363
- oDelta.resetChanges();
29376
+ await this.waitForChanges(assert, "collapse Gamma");
29377
+
29378
+ checkTable("after collapsing Gamma", assert, oTable, [
29379
+ "/EMPLOYEES('1')",
29380
+ "/EMPLOYEES('2')",
29381
+ "/EMPLOYEES('5')"
29382
+ ], [
29383
+ [undefined, 2, "1", "0", "Beta"],
29384
+ [false, 2, "2", "0", "Gamma"],
29385
+ [undefined, 2, "5", "0", "Zeta"]
29386
+ ], 5);
29387
+
29388
+ this.expectRequest("DELETE EMPLOYEES('1')")
29389
+ .expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
29390
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
29391
+ + ",NodeProperty='ID',Levels=3)"
29392
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
29393
+ + "&$skip=5&$top=1", {
29394
+ value : [{
29395
+ DescendantCount : "0",
29396
+ DistanceFromRoot : "1",
29397
+ DrillState : "leaf",
29398
+ ID : "6",
29399
+ MANAGER_ID : "0",
29400
+ Name : "Eta"
29401
+ }]
29402
+ })
29403
+ .expectChange("expanded", [, false, undefined])
29404
+ .expectChange("name", [, "Gamma", "Zeta", "Eta"]);
28364
29405
 
28365
29406
  await Promise.all([
28366
- checkCanceled(assert, oDeleteDeltaPromise),
28367
- this.waitForChanges(assert, "reinsert delta")
29407
+ oTable.getRows()[0].getBindingContext().delete(),
29408
+ this.waitForChanges(assert, "delete Beta")
28368
29409
  ]);
28369
29410
 
28370
- checkTable("after reinsert", assert, oTable, [
28371
- "/EMPLOYEES('1')",
29411
+ checkTable("after delete Beta", assert, oTable, [
29412
+ "/EMPLOYEES('2')",
29413
+ "/EMPLOYEES('5')",
29414
+ "/EMPLOYEES('6')"
29415
+ ], [
29416
+ [false, 2, "2", "0", "Gamma"],
29417
+ [undefined, 2, "5", "0", "Zeta"],
29418
+ [undefined, 2, "6", "0", "Eta"]
29419
+ ], 4);
29420
+
29421
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
29422
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
29423
+ + ",NodeProperty='ID',Levels=3)"
29424
+ + "&$select=DescendantCount,DistanceFromRoot,DrillState,ID,MANAGER_ID,Name"
29425
+ + "&$skip=3&$top=1", {
29426
+ value : [{
29427
+ DescendantCount : "0",
29428
+ DistanceFromRoot : "2",
29429
+ DrillState : "leaf",
29430
+ ID : "4",
29431
+ MANAGER_ID : "2",
29432
+ Name : "Epsilon"
29433
+ }]
29434
+ })
29435
+ .expectChange("expanded", [, true])
29436
+ .expectChange("name", [,, "Delta", "Epsilon"]);
29437
+
29438
+ oTable.getRows()[0].getBindingContext().expand();
29439
+
29440
+ await this.waitForChanges(assert, "expand Gamma");
29441
+
29442
+ checkTable("after expand Gamma", assert, oTable, [
29443
+ "/EMPLOYEES('2')",
28372
29444
  "/EMPLOYEES('3')",
28373
- "/EMPLOYEES('4')"
29445
+ "/EMPLOYEES('4')",
29446
+ "/EMPLOYEES('5')",
29447
+ "/EMPLOYEES('6')"
28374
29448
  ], [
28375
- [true, 1, "1", "", "Beta"],
28376
- [undefined, 2, "3", "1", "Delta"],
28377
- [false, 1, "4", "", "Epsilon"]
28378
- ], 3);
29449
+ [true, 2, "2", "0", "Gamma"],
29450
+ [undefined, 3, "3", "2", "Delta"],
29451
+ [undefined, 3, "4", "2", "Epsilon"]
29452
+ ], 6);
28379
29453
  });
28380
29454
 
28381
29455
  //*********************************************************************************************
@@ -28394,8 +29468,15 @@ sap.ui.define([
28394
29468
  // Move "Beta" so that "Gamma" becomes its parent (no change to context's index, but a persisted
28395
29469
  // node (again) becomes "created persisted"). Observe property change events for "@odata.etag".
28396
29470
  // JIRA: CPOUI5ODATAV4-2226
28397
- QUnit.test("Recursive Hierarchy: create new children", function (assert) {
28398
- var oBeta, oBetaCreated, oGamma, oGammaCreated, oListBinding, fnRespond, oRoot, oTable;
29471
+ //
29472
+ // Create a new root via "@$ui5.node.parent" : null (JIRA: CPOUI5ODATAV4-2355)
29473
+ //
29474
+ // "Refresh single" for stale elements; keep same context instance for created nodes throughout
29475
+ // collapse and side effects.
29476
+ // JIRA: CPOUI5ODATAV4-2374
29477
+ QUnit.test("Recursive Hierarchy: create new children, move 'em", function (assert) {
29478
+ var oBeta, oBetaCreated, oGamma, oGammaCreated, oListBinding, oNewRoot, fnRespond, oRoot,
29479
+ oTable;
28399
29480
 
28400
29481
  const oModel = this.createSpecialCasesModel({autoExpandSelect : true});
28401
29482
  const sFriend = "/Artists(ArtistID='99',IsActiveEntity=false)/_Friend";
@@ -28450,11 +29531,6 @@ sap.ui.define([
28450
29531
  ]);
28451
29532
  assert.strictEqual(oRoot.getIndex(), 0);
28452
29533
 
28453
- assert.throws(function () {
28454
- // code under test (missing "@$ui5.node.parent")
28455
- oListBinding.create({}, /*bSkipRefresh*/true);
28456
- }); // TypeError: Cannot read properties of undefined (reading 'getCanonicalPath')
28457
-
28458
29534
  // code under test (JIRA: CPOUI5ODATAV4-2272)
28459
29535
  const oLostChild = oListBinding.create({
28460
29536
  "@$ui5.node.parent" : oRoot,
@@ -28712,6 +29788,8 @@ sap.ui.define([
28712
29788
  ["", "", "", "", ""],
28713
29789
  ["", "", "", "", ""]
28714
29790
  ]);
29791
+ assert.strictEqual(oBeta.getModel(), oModel, "not destroyed by collapse");
29792
+ assert.strictEqual(oGamma.getModel(), oModel, "not destroyed by collapse");
28715
29793
 
28716
29794
  that.expectRequest(sFriend.slice(1) + "?$select=ArtistID,IsActiveEntity,Name,_/NodeID"
28717
29795
  + "&$filter=ArtistID eq '0' and IsActiveEntity eq false", {
@@ -28726,38 +29804,28 @@ sap.ui.define([
28726
29804
  .expectChange("etag", ["etag0.1"])
28727
29805
  .expectChange("name", ["Alpha #1"]);
28728
29806
 
28729
- oBeta = oGamma = null; // Note: side effect eventually destroys these!
28730
-
28731
29807
  return Promise.all([
28732
29808
  // code under test
28733
29809
  oListBinding.getHeaderContext().requestSideEffects(["Name"]),
28734
29810
  that.waitForChanges(assert, "side effect: Name for all rows")
28735
29811
  ]);
28736
29812
  }).then(function () {
28737
- that.expectRequest(sFriend.slice(1) + "?$apply=descendants($root" + sFriend
28738
- + ",OrgChart,_/NodeID,filter(ArtistID eq '0' and IsActiveEntity eq false),1)"
28739
- + "&$select=ArtistID,IsActiveEntity,Name,_/DrillState,_/NodeID"
28740
- + "&$skip=0&$top=2", {
28741
- value : [{ //TODO Gamma might not be $skip=0!
29813
+ that.expectRequest(sFriend.slice(1) + "(ArtistID='2',IsActiveEntity=false)"
29814
+ + "?$select=ArtistID,IsActiveEntity,Name,_/DrillState,_/NodeID", {
28742
29815
  "@odata.etag" : "etag2.3", // updated
28743
29816
  ArtistID : "2",
28744
29817
  IsActiveEntity : false,
28745
29818
  Name : "Gamma #1", // "side effect"
28746
- _ : {
28747
- DrillState : "leaf",
28748
- NodeID : "2,false"
28749
- }
28750
- }, {
29819
+ _ : null // not available w/ RAP for a non-hierarchical request
29820
+ })
29821
+ .expectRequest(sFriend.slice(1) + "(ArtistID='1',IsActiveEntity=false)"
29822
+ + "?$select=ArtistID,IsActiveEntity,Name,_/DrillState,_/NodeID", {
28751
29823
  "@odata.etag" : "etag1.3", // updated
28752
29824
  ArtistID : "1",
28753
29825
  IsActiveEntity : false,
28754
29826
  Name : "Beta #1", // "side effect"
28755
- _ : {
28756
- DrillState : "leaf",
28757
- NodeID : "1,false"
28758
- }
28759
- }]
28760
- })
29827
+ _ : null // not available w/ RAP for a non-hierarchical request
29828
+ })
28761
29829
  .expectChange("etag", [, "etag2.3", "etag1.3"])
28762
29830
  .expectChange("name", [, "Gamma #1", "Beta #1"]);
28763
29831
 
@@ -28772,39 +29840,39 @@ sap.ui.define([
28772
29840
  sFriend + "(ArtistID='1',IsActiveEntity=false)"
28773
29841
  ], [
28774
29842
  [undefined, true, 1, "etag0.1", "Alpha #1"],
28775
- [undefined, undefined, 2, "etag2.3", "Gamma #1"],
28776
- [undefined, undefined, 2, "etag1.3", "Beta #1"]
29843
+ [false, undefined, 2, "etag2.3", "Gamma #1"],
29844
+ [false, undefined, 2, "etag1.3", "Beta #1"]
28777
29845
  ]);
28778
- [, oGamma, oBeta] = oListBinding.getCurrentContexts();
29846
+ const aCurrentContexts = oListBinding.getCurrentContexts();
29847
+ assert.strictEqual(oRoot, aCurrentContexts[0]);
29848
+ assert.strictEqual(oGamma, aCurrentContexts[1]);
29849
+ assert.strictEqual(oBeta, aCurrentContexts[2]);
28779
29850
 
28780
29851
  assert.strictEqual(oGamma.getIndex(), 1);
28781
29852
  assert.deepEqual(oGamma.getObject(), {
29853
+ "@$ui5.context.isTransient" : false,
28782
29854
  "@$ui5.node.level" : 2,
28783
29855
  "@odata.etag" : "etag2.3",
28784
29856
  ArtistID : "2",
28785
29857
  IsActiveEntity : false,
28786
29858
  Name : "Gamma #1",
28787
- _ : {
28788
- NodeID : "2,false"
28789
- }
29859
+ _ : null // Note: NodeID still unknown
28790
29860
  });
28791
- assert.strictEqual(oGamma.isTransient(), undefined, "persisted");
28792
- assert.strictEqual(oGamma.created(), undefined);
29861
+ assert.strictEqual(oGamma.isTransient(), false, "created persisted");
29862
+ assert.strictEqual(oGamma.created(), oGammaCreated, "unchanged");
28793
29863
 
28794
29864
  assert.strictEqual(oBeta.getIndex(), 2);
28795
29865
  assert.deepEqual(oBeta.getObject(), {
28796
- // "@$ui5.context.isTransient" deleted by #requestSideEffects/#expand
29866
+ "@$ui5.context.isTransient" : false,
28797
29867
  "@$ui5.node.level" : 2,
28798
29868
  "@odata.etag" : "etag1.3",
28799
29869
  ArtistID : "1",
28800
29870
  IsActiveEntity : false,
28801
29871
  Name : "Beta #1",
28802
- _ : {
28803
- NodeID : "1,false"
28804
- }
29872
+ _ : null // Note: NodeID still unknown
28805
29873
  });
28806
- assert.strictEqual(oBeta.isTransient(), undefined, "persisted");
28807
- assert.strictEqual(oBeta.created(), undefined);
29874
+ assert.strictEqual(oBeta.isTransient(), false, "created persisted");
29875
+ assert.strictEqual(oBeta.created(), oBetaCreated, "unchanged");
28808
29876
 
28809
29877
  return Promise.all([
28810
29878
  // code under test
@@ -28837,7 +29905,7 @@ sap.ui.define([
28837
29905
  sFriend + "(ArtistID='1',IsActiveEntity=false)"
28838
29906
  ], [
28839
29907
  [undefined, true, 1, "etag0.1", "Alpha #1"],
28840
- [undefined, true, 2, "etag2.3", "Gamma #1"],
29908
+ [false, true, 2, "etag2.3", "Gamma #1"],
28841
29909
  [false, undefined, 3, "etag1.4", "Beta #1"]
28842
29910
  ]);
28843
29911
  const aCurrentContexts = oListBinding.getCurrentContexts();
@@ -28847,46 +29915,171 @@ sap.ui.define([
28847
29915
 
28848
29916
  assert.strictEqual(oGamma.getIndex(), 1);
28849
29917
  assert.deepEqual(oGamma.getObject(), {
29918
+ "@$ui5.context.isTransient" : false,
28850
29919
  "@$ui5.node.isExpanded" : true,
28851
29920
  "@$ui5.node.level" : 2,
28852
29921
  "@odata.etag" : "etag2.3",
28853
29922
  ArtistID : "2",
28854
29923
  IsActiveEntity : false,
28855
29924
  Name : "Gamma #1",
28856
- _ : {
28857
- NodeID : "2,false"
28858
- }
29925
+ _ : null // Note: NodeID still unknown
28859
29926
  });
28860
- assert.strictEqual(oGamma.isTransient(), undefined, "persisted");
28861
- assert.strictEqual(oGamma.created(), undefined);
29927
+ assert.strictEqual(oGamma.isTransient(), false, "created persisted");
29928
+ assert.strictEqual(oGamma.created(), oGammaCreated, "unchanged");
28862
29929
 
28863
29930
  assert.strictEqual(oBeta.getIndex(), 2); // unchanged by #move
28864
29931
  assert.deepEqual(oBeta.getObject(), {
28865
- "@$ui5.context.isTransient" : false, // "moved"
29932
+ "@$ui5.context.isTransient" : false,
28866
29933
  "@$ui5.node.level" : 3,
28867
29934
  "@odata.etag" : "etag1.4",
28868
29935
  ArtistID : "1",
28869
29936
  IsActiveEntity : false,
28870
29937
  Name : "Beta #1",
28871
- _ : {
28872
- NodeID : "1,false"
28873
- }
29938
+ _ : null // Note: NodeID still unknown
28874
29939
  });
28875
29940
  assert.strictEqual(oBeta.isTransient(), false, "created persisted");
28876
- assert.ok(oBeta.created() instanceof Promise);
29941
+ assert.strictEqual(oBeta.created(), oBetaCreated, "unchanged");
28877
29942
 
28878
29943
  return oBeta.created(); // to prove that it's not rejected
29944
+ }).then(function () {
29945
+ that.expectChange("etag", [undefined, "etag0.1", "etag2.3"])
29946
+ .expectChange("name", ["Aleph", "Alpha #1", "Gamma #1"])
29947
+ .expectRequest({
29948
+ method : "POST",
29949
+ url : sFriend.slice(1),
29950
+ payload : {
29951
+ // not needed: "BestFriend@odata.bind" : null,
29952
+ Name : "Aleph"
29953
+ }
29954
+ }, {
29955
+ "@odata.etag" : "etag9.0",
29956
+ ArtistID : "9",
29957
+ IsActiveEntity : false,
29958
+ Name : "Aleph: ℵ" // side effect
29959
+ })
29960
+ .expectChange("etag", ["etag9.0"])
29961
+ .expectChange("name", ["Aleph: ℵ"]);
29962
+
29963
+ // code under test (JIRA: CPOUI5ODATAV4-2355)
29964
+ oNewRoot = oListBinding.create({
29965
+ "@$ui5.node.parent" : null,
29966
+ Name : "Aleph"
29967
+ }, /*bSkipRefresh*/true);
29968
+
29969
+ assert.strictEqual(oNewRoot.getIndex(), 0);
29970
+
29971
+ return Promise.all([
29972
+ oNewRoot.created(),
29973
+ that.waitForChanges(assert, "create new root")
29974
+ ]);
29975
+ }).then(function () {
29976
+ checkTable("after create new root", assert, oTable, [
29977
+ sFriend + "(ArtistID='9',IsActiveEntity=false)",
29978
+ sFriend + "(ArtistID='0',IsActiveEntity=false)",
29979
+ sFriend + "(ArtistID='2',IsActiveEntity=false)",
29980
+ sFriend + "(ArtistID='1',IsActiveEntity=false)"
29981
+ ], [
29982
+ [false, undefined, 1, "etag9.0", "Aleph: ℵ"],
29983
+ [undefined, true, 1, "etag0.1", "Alpha #1"],
29984
+ [false, true, 2, "etag2.3", "Gamma #1"]
29985
+ ]);
29986
+ assert.strictEqual(oNewRoot.isTransient(), false, "created persisted");
29987
+
29988
+ that.expectRequest(sFriend.slice(1) + "?$select=ArtistID,IsActiveEntity,Name,_/NodeID"
29989
+ + "&$filter=ArtistID eq '9' and IsActiveEntity eq false"
29990
+ + " or ArtistID eq '0' and IsActiveEntity eq false"
29991
+ + " or ArtistID eq '2' and IsActiveEntity eq false"
29992
+ + " or ArtistID eq '1' and IsActiveEntity eq false"
29993
+ + "&$top=4", {
29994
+ value : [{
29995
+ "@odata.etag" : "etag9.1",
29996
+ ArtistID : "9",
29997
+ IsActiveEntity : false,
29998
+ Name : "Aleph #2",
29999
+ _ : null // not available w/ RAP for a non-hierarchical request
30000
+ }, {
30001
+ "@odata.etag" : "etag0.2",
30002
+ ArtistID : "0",
30003
+ IsActiveEntity : false,
30004
+ Name : "Alpha #2",
30005
+ _ : null // not available w/ RAP for a non-hierarchical request
30006
+ }, {
30007
+ "@odata.etag" : "etag2.4",
30008
+ ArtistID : "2",
30009
+ IsActiveEntity : false,
30010
+ Name : "Gamma #2",
30011
+ _ : null // not available w/ RAP for a non-hierarchical request
30012
+ }, {
30013
+ "@odata.etag" : "etag1.5",
30014
+ ArtistID : "1",
30015
+ IsActiveEntity : false,
30016
+ Name : "Beta #2",
30017
+ _ : null // not available w/ RAP for a non-hierarchical request
30018
+ }]
30019
+ })
30020
+ .expectChange("etag", ["etag9.1", "etag0.2", "etag2.4"])
30021
+ .expectChange("name", ["Aleph #2", "Alpha #2", "Gamma #2"]);
30022
+
30023
+ return Promise.all([
30024
+ // code under test
30025
+ oListBinding.getHeaderContext().requestSideEffects(["Name"]),
30026
+ that.waitForChanges(assert, "side effect again: Name for all rows")
30027
+ ]);
30028
+ }).then(function () {
30029
+ checkTable("after side effect again: Name for all rows", assert, oTable, [
30030
+ sFriend + "(ArtistID='9',IsActiveEntity=false)",
30031
+ sFriend + "(ArtistID='0',IsActiveEntity=false)",
30032
+ sFriend + "(ArtistID='2',IsActiveEntity=false)",
30033
+ sFriend + "(ArtistID='1',IsActiveEntity=false)"
30034
+ ], [
30035
+ [false, undefined, 1, "etag9.1", "Aleph #2"],
30036
+ [undefined, true, 1, "etag0.2", "Alpha #2"],
30037
+ [false, true, 2, "etag2.4", "Gamma #2"]
30038
+ ]);
30039
+ assert.strictEqual(oBeta, oListBinding.getAllCurrentContexts()[3], "same instance");
30040
+
30041
+ that.expectChange("etag", [, "etag0.2", "etag2.4", "etag1.5"])
30042
+ .expectChange("name", [, "Alpha #2", "Gamma #2", "Beta #2"]);
30043
+
30044
+ oTable.setFirstVisibleRow(1);
30045
+
30046
+ return that.waitForChanges(assert, "scroll down to Beta");
30047
+ }).then(function () {
30048
+ checkTable("after scroll down to Beta", assert, oTable, [
30049
+ sFriend + "(ArtistID='9',IsActiveEntity=false)",
30050
+ sFriend + "(ArtistID='0',IsActiveEntity=false)",
30051
+ sFriend + "(ArtistID='2',IsActiveEntity=false)",
30052
+ sFriend + "(ArtistID='1',IsActiveEntity=false)"
30053
+ ], [
30054
+ [undefined, true, 1, "etag0.2", "Alpha #2"],
30055
+ [false, true, 2, "etag2.4", "Gamma #2"],
30056
+ [false, undefined, 3, "etag1.5", "Beta #2"]
30057
+ ]);
30058
+ assert.strictEqual(oBeta, oListBinding.getCurrentContexts()[2], "same instance");
30059
+ assert.strictEqual(oBeta.isTransient(), false, "created persisted");
30060
+ assert.strictEqual(oBeta.created(), oBetaCreated, "unchanged");
28879
30061
  });
28880
30062
  });
28881
30063
 
28882
30064
  //*********************************************************************************************
28883
- // Scenario: Show the first level of a recursive hierarchy ("Alpha", "Omega"), expand "Alpha"
28884
- // and "Beta" and collapse "Beta" again. Move "Alpha" so that "Omega" becomes its parent. Check
28885
- // that its children are moved as well. Expand "Beta" again and check the level of its children.
28886
- // "Alpha" is either moved as a node with children or first collapsed and later expanded.
30065
+ // Scenario: Show the first level of a recursive hierarchy ("Alpha", "Omega"), expand "Alpha".
30066
+ // Maybe expand "Beta" and collapse it again. Move "Alpha" so that "Omega" becomes its parent,
30067
+ // either as an expanded node with children or by first collapsing and later expanding. Check
30068
+ // that its children are moved as well.
28887
30069
  // JIRA: CPOUI5ODATAV4-2325
30070
+ //
30071
+ // Move "Kappa" so that "Beta" becomes its parent, thus expanding it again, then check the
30072
+ // level of the latter's children.
30073
+ // JIRA: CPOUI5ODATAV4-2326
30074
+ //
30075
+ // A failed move must not leave the node collapsed (JIRA: CPOUI5ODATAV4-2343)
30076
+ //
30077
+ // Determine the parent nodes of "Alpha", "Beta", "Kappa", and "Omega".
30078
+ // JIRA: CPOUI5ODATAV4-2323
28888
30079
  [false, true].forEach((bMoveCollapsed) => {
28889
- const sTitle = `Recursive Hierarchy: move node w/ children, collapsed=${bMoveCollapsed}`;
30080
+ [false, true].forEach((bExpandCollapseBeta) => {
30081
+ const sTitle = `Recursive Hierarchy: move node w/ children, collapsed=${bMoveCollapsed},
30082
+ "Beta" expanded/collapsed before=${bExpandCollapseBeta}`;
28890
30083
 
28891
30084
  QUnit.test(sTitle, async function (assert) {
28892
30085
  const oModel = this.createTeaBusiModel({autoExpandSelect : true});
@@ -28894,7 +30087,7 @@ sap.ui.define([
28894
30087
  <t:Table id="table" rows="{path : '/EMPLOYEES',
28895
30088
  parameters : {
28896
30089
  $$aggregation : {hierarchyQualifier : 'OrgChart'}
28897
- }}" threshold="0" visibleRowCount="5">
30090
+ }}" threshold="0" visibleRowCount="7">
28898
30091
  <Text text="{= %{@$ui5.node.isExpanded} }"/>
28899
30092
  <Text text="{= %{@$ui5.node.level} }"/>
28900
30093
  <Text id="id" text="{ID}"/>
@@ -28913,7 +30106,7 @@ sap.ui.define([
28913
30106
  this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
28914
30107
  + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
28915
30108
  + ",NodeProperty='ID',Levels=1)"
28916
- + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=5", {
30109
+ + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=7", {
28917
30110
  "@odata.count" : "2",
28918
30111
  value : [{
28919
30112
  AGE : 60,
@@ -28939,17 +30132,14 @@ sap.ui.define([
28939
30132
  "/EMPLOYEES('9')"
28940
30133
  ], [
28941
30134
  [false, 1, "0", "", "Alpha", 60],
28942
- [undefined, 1, "9", "", "Omega", 69],
28943
- ["", "", "", "", "", ""],
28944
- ["", "", "", "", "", ""],
28945
- ["", "", "", "", "", ""]
30135
+ [undefined, 1, "9", "", "Omega", 69]
28946
30136
  ]);
28947
30137
  const oAlpha = oTable.getRows()[0].getBindingContext();
28948
30138
  const oOmega = oTable.getRows()[1].getBindingContext();
28949
30139
 
28950
30140
  this.expectRequest("EMPLOYEES?$apply=descendants($root/EMPLOYEES,OrgChart,ID"
28951
30141
  + ",filter(ID eq '0'),1)"
28952
- + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=5", {
30142
+ + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=7", {
28953
30143
  "@odata.count" : "3",
28954
30144
  value : [{
28955
30145
  AGE : 55,
@@ -28990,71 +30180,120 @@ sap.ui.define([
28990
30180
  [undefined, 2, "3", "0", "Lambda", 57],
28991
30181
  [undefined, 1, "9", "", "Omega", 69]
28992
30182
  ]);
28993
- const oBeta = oTable.getRows()[1].getBindingContext();
28994
30183
 
28995
- this.expectRequest("EMPLOYEES?$apply=descendants($root/EMPLOYEES,OrgChart,ID"
28996
- + ",filter(ID eq '1'),1)"
28997
- + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=5", {
28998
- "@odata.count" : "2",
28999
- value : [{
29000
- AGE : 41,
29001
- DrillState : "leaf",
29002
- ID : "1.1",
29003
- MANAGER_ID : "1",
29004
- Name : "Gamma"
29005
- }, {
29006
- AGE : 42,
29007
- DrillState : "leaf",
29008
- ID : "1.2",
29009
- MANAGER_ID : "1",
29010
- Name : "Zeta"
29011
- }]
29012
- })
29013
- .expectChange("id", [,, "1.1", "1.2", "2"]);
30184
+ const oExpandBetaResponse = {
30185
+ "@odata.count" : "2",
30186
+ value : [{
30187
+ AGE : 41,
30188
+ DrillState : "leaf",
30189
+ ID : "1.1",
30190
+ MANAGER_ID : "1",
30191
+ Name : "Gamma"
30192
+ }, {
30193
+ AGE : 42,
30194
+ DrillState : "leaf",
30195
+ ID : "1.2",
30196
+ MANAGER_ID : "1",
30197
+ Name : "Zeta"
30198
+ }]
30199
+ };
30200
+ if (bExpandCollapseBeta) {
30201
+ const oBeta = oTable.getRows()[1].getBindingContext();
29014
30202
 
29015
- oBeta.expand();
30203
+ this.expectRequest("EMPLOYEES?$apply=descendants($root/EMPLOYEES,OrgChart,ID"
30204
+ + ",filter(ID eq '1'),1)"
30205
+ + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$count=true&$skip=0&$top=7",
30206
+ oExpandBetaResponse)
30207
+ .expectChange("id", [,, "1.1", "1.2", "2", "3", "9"]);
29016
30208
 
29017
- await this.waitForChanges(assert, "expand 1 (Beta)");
30209
+ oBeta.expand();
29018
30210
 
29019
- checkTable("after expand 1 (Beta)", assert, oTable, [
29020
- "/EMPLOYEES('0')",
29021
- "/EMPLOYEES('1')",
29022
- "/EMPLOYEES('1.1')",
29023
- "/EMPLOYEES('1.2')",
29024
- "/EMPLOYEES('2')",
29025
- "/EMPLOYEES('3')",
29026
- "/EMPLOYEES('9')"
29027
- ], [
29028
- [true, 1, "0", "", "Alpha", 60],
29029
- [true, 2, "1", "0", "Beta", 55],
29030
- [undefined, 3, "1.1", "1", "Gamma", 41],
29031
- [undefined, 3, "1.2", "1", "Zeta", 42],
29032
- [undefined, 2, "2", "0", "Kappa", 56]
29033
- ]);
30211
+ await this.waitForChanges(assert, "expand 1 (Beta)");
29034
30212
 
29035
- this.expectChange("id", [,, "2", "3", "9"]);
30213
+ checkTable("after expand 1 (Beta)", assert, oTable, [
30214
+ "/EMPLOYEES('0')",
30215
+ "/EMPLOYEES('1')",
30216
+ "/EMPLOYEES('1.1')",
30217
+ "/EMPLOYEES('1.2')",
30218
+ "/EMPLOYEES('2')",
30219
+ "/EMPLOYEES('3')",
30220
+ "/EMPLOYEES('9')"
30221
+ ], [
30222
+ [true, 1, "0", "", "Alpha", 60],
30223
+ [true, 2, "1", "0", "Beta", 55],
30224
+ [undefined, 3, "1.1", "1", "Gamma", 41],
30225
+ [undefined, 3, "1.2", "1", "Zeta", 42],
30226
+ [undefined, 2, "2", "0", "Kappa", 56],
30227
+ [undefined, 2, "3", "0", "Lambda", 57],
30228
+ [undefined, 1, "9", "", "Omega", 69]
30229
+ ]);
29036
30230
 
29037
- oBeta.collapse();
30231
+ this.expectChange("id", [,, "2", "3", "9"]);
29038
30232
 
29039
- await this.waitForChanges(assert, "collapse 1 (Beta)");
30233
+ oBeta.collapse();
29040
30234
 
29041
- checkTable("after collapse 1 (Beta)", assert, oTable, [
29042
- "/EMPLOYEES('0')",
29043
- "/EMPLOYEES('1')",
29044
- "/EMPLOYEES('2')",
29045
- "/EMPLOYEES('3')",
29046
- "/EMPLOYEES('9')"
29047
- ], [
29048
- [true, 1, "0", "", "Alpha", 60],
29049
- [false, 2, "1", "0", "Beta", 55],
29050
- [undefined, 2, "2", "0", "Kappa", 56],
29051
- [undefined, 2, "3", "0", "Lambda", 57],
29052
- [undefined, 1, "9", "", "Omega", 69]
29053
- ]);
30235
+ await this.waitForChanges(assert, "collapse 1 (Beta)");
30236
+
30237
+ checkTable("after collapse 1 (Beta)", assert, oTable, [
30238
+ "/EMPLOYEES('0')",
30239
+ "/EMPLOYEES('1')",
30240
+ "/EMPLOYEES('2')",
30241
+ "/EMPLOYEES('3')",
30242
+ "/EMPLOYEES('9')"
30243
+ ], [
30244
+ [true, 1, "0", "", "Alpha", 60],
30245
+ [false, 2, "1", "0", "Beta", 55],
30246
+ [undefined, 2, "2", "0", "Kappa", 56],
30247
+ [undefined, 2, "3", "0", "Lambda", 57],
30248
+ [undefined, 1, "9", "", "Omega", 69]
30249
+ ]);
30250
+ } // end if (bExpandCollapseBeta)
29054
30251
 
29055
30252
  if (bMoveCollapsed) {
29056
30253
  this.expectChange("id", [, "9"]);
29057
30254
  oAlpha.collapse();
30255
+ } else { // "A failed move must not leave the node collapsed"
30256
+ const oBeta = oTable.getRows()[1].getBindingContext();
30257
+
30258
+ this.expectEvents(assert, "sap.ui.model.odata.v4.ODataListBinding: /EMPLOYEES", [])
30259
+ .expectRequest({
30260
+ headers : {
30261
+ Prefer : "return=minimal"
30262
+ },
30263
+ method : "PATCH",
30264
+ url : "EMPLOYEES('0')",
30265
+ payload : {
30266
+ "EMPLOYEE_2_MANAGER@odata.bind" : "EMPLOYEES('9')"
30267
+ }
30268
+ }, createErrorInsideBatch());
30269
+
30270
+ await Promise.all([
30271
+ oAlpha.move({parent : oOmega}).then(mustFail(assert), function (oError) {
30272
+ assert.strictEqual(oError.message, "Request intentionally failed");
30273
+ }), // (JIRA: CPOUI5ODATAV4-2343)
30274
+ this.waitForChanges(assert, "move 0 (Alpha) to 9 (Omega) *FAILS*")
30275
+ ]);
30276
+
30277
+ this.expectEvents(assert, "sap.ui.model.odata.v4.ODataListBinding: /EMPLOYEES", [
30278
+ [, "change", {reason : "change"}] // caused by ODLB#getAllCurrentContexts
30279
+ ]);
30280
+ checkTable("after failed move", assert, oTable, [
30281
+ "/EMPLOYEES('0')",
30282
+ "/EMPLOYEES('1')",
30283
+ "/EMPLOYEES('2')",
30284
+ "/EMPLOYEES('3')",
30285
+ "/EMPLOYEES('9')"
30286
+ ], [
30287
+ [true, 1, "0", "", "Alpha", 60],
30288
+ [false, 2, "1", "0", "Beta", 55],
30289
+ [undefined, 2, "2", "0", "Kappa", 56],
30290
+ [undefined, 2, "3", "0", "Lambda", 57],
30291
+ [undefined, 1, "9", "", "Omega", 69]
30292
+ ]);
30293
+ assert.strictEqual(oTable.getRows()[1].getBindingContext(), oBeta, "unchanged");
30294
+
30295
+ // wait for UI changes caused by "change" event above
30296
+ await resolveLater(undefined, /*iDelay*/1);
29058
30297
  }
29059
30298
 
29060
30299
  this.expectEvents(assert, "sap.ui.model.odata.v4.ODataListBinding: /EMPLOYEES", [
@@ -29100,9 +30339,254 @@ sap.ui.define([
29100
30339
  [undefined, 3, "2", "0", "Kappa", 56],
29101
30340
  [undefined, 3, "3", "0", "Lambda", 57]
29102
30341
  ]);
30342
+ const oBeta = oTable.getRows()[2].getBindingContext();
30343
+ const oKappa = oTable.getRows()[3].getBindingContext();
30344
+
30345
+ const iBatchNo = this.iBatchNo + 1; // don't care about exact no., but use twice below
30346
+ this.expectEvents(assert, "sap.ui.model.odata.v4.ODataListBinding: /EMPLOYEES", [
30347
+ [, "change", {reason : "change"}]
30348
+ ])
30349
+ .expectRequest({
30350
+ batchNo : iBatchNo,
30351
+ headers : {
30352
+ Prefer : "return=minimal"
30353
+ },
30354
+ method : "PATCH",
30355
+ url : "EMPLOYEES('2')",
30356
+ payload : {
30357
+ "EMPLOYEE_2_MANAGER@odata.bind" : "EMPLOYEES('1')"
30358
+ }
30359
+ }) // 204 No Content
30360
+ .expectChange("id", [,,,, "1.1", "1.2", "3"]);
30361
+ if (!bExpandCollapseBeta) {
30362
+ this.expectRequest({
30363
+ batchNo : iBatchNo,
30364
+ url : "EMPLOYEES?$apply=descendants($root/EMPLOYEES,OrgChart,ID"
30365
+ + ",filter(ID eq '1'),1)"
30366
+ + "&$select=AGE,DrillState,ID,MANAGER_ID,Name&$count=true"
30367
+ + "&$filter=not (ID eq '2')&$skip=0&$top=6"
30368
+ }, oExpandBetaResponse);
30369
+ }
30370
+
30371
+ await Promise.all([
30372
+ oKappa.move({parent : oBeta}),
30373
+ this.waitForChanges(assert, "move 2 (Kappa) to collapsed 1 (Beta)")
30374
+ ]);
30375
+
30376
+ checkTable("after move 2 (Kappa) to collapsed 1 (Beta)", assert, oTable, [
30377
+ "/EMPLOYEES('9')",
30378
+ "/EMPLOYEES('0')",
30379
+ "/EMPLOYEES('1')",
30380
+ "/EMPLOYEES('2')",
30381
+ "/EMPLOYEES('1.1')",
30382
+ "/EMPLOYEES('1.2')",
30383
+ "/EMPLOYEES('3')"
30384
+ ], [
30385
+ [true, 1, "9", "", "Omega", 69],
30386
+ [true, 2, "0", ""/*TODO "9"*/, "Alpha", 60],
30387
+ [true, 3, "1", "0", "Beta", 55],
30388
+ [undefined, 4, "2", "0"/*TODO "1"*/, "Kappa", 56],
30389
+ [undefined, 4, "1.1", "1", "Gamma", 41],
30390
+ [undefined, 4, "1.2", "1", "Zeta", 42],
30391
+ [undefined, 3, "3", "0", "Lambda", 57]
30392
+ ]);
30393
+
30394
+ // code under test
30395
+ assert.strictEqual(oBeta.isAncestorOf(oKappa), true, "JIRA: CPOUI5ODATAV4-2337");
30396
+ assert.strictEqual(oOmega.isAncestorOf(oKappa), true, "JIRA: CPOUI5ODATAV4-2337");
30397
+ assert.strictEqual(oKappa.isAncestorOf(oOmega), false, "JIRA: CPOUI5ODATAV4-2337");
30398
+
30399
+ // code under test
30400
+ assert.strictEqual(oKappa.getParent(), oBeta, "JIRA: CPOUI5ODATAV4-2323");
30401
+ assert.strictEqual(oBeta.getParent(), oAlpha, "JIRA: CPOUI5ODATAV4-2323");
30402
+ assert.strictEqual(oAlpha.getParent(), oOmega, "JIRA: CPOUI5ODATAV4-2323");
30403
+ assert.strictEqual(oOmega.getParent(), null, "JIRA: CPOUI5ODATAV4-2323");
30404
+ });
29103
30405
  });
29104
30406
  });
29105
30407
 
30408
+ //*********************************************************************************************
30409
+ // Scenario: Show the first level of a recursive hierarchy ("Alpha", "Omega"), expand "Alpha".
30410
+ // Scroll to "Delta". Request side effects for the list binding. The parent node will not
30411
+ // anymore have a context in the list binding.
30412
+ // Determine the parent node of "Delta" with #getParent. It is not available at the moment.
30413
+ // Try to request the parent node of "Alpha" and "Delta".
30414
+ // JIRA: CPOUI5ODATAV4-2342
30415
+ QUnit.test("get and request Parent after requestSideEffects", async function (assert) {
30416
+ const oModel = this.createTeaBusiModel({autoExpandSelect : true});
30417
+ const sView = `
30418
+ <t:Table id="table" rows="{path : '/EMPLOYEES',
30419
+ parameters : {
30420
+ $$aggregation : {hierarchyQualifier : 'OrgChart'}
30421
+ }}" threshold="0" visibleRowCount="2">
30422
+ <Text text="{= %{@$ui5.node.isExpanded} }"/>
30423
+ <Text text="{= %{@$ui5.node.level} }"/>
30424
+ <Text id="id" text="{ID}"/>
30425
+ <Text text="{Name}"/>
30426
+ </t:Table>`;
30427
+
30428
+ // 0 Alpha
30429
+ // 1 Beta
30430
+ // 2 Gamma
30431
+ // 3 Delta
30432
+ // 4 Epsilon
30433
+ // 9 Omega
30434
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
30435
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
30436
+ + ",NodeProperty='ID',Levels=1)"
30437
+ + "&$select=DrillState,ID,Name&$count=true&$skip=0&$top=2", {
30438
+ "@odata.count" : "2",
30439
+ value : [{
30440
+ DrillState : "collapsed",
30441
+ ID : "0",
30442
+ Name : "Alpha"
30443
+ }, {
30444
+ DrillState : "leaf",
30445
+ ID : "9",
30446
+ Name : "Omega"
30447
+ }]
30448
+ })
30449
+ .expectChange("id", ["0", "9"]);
30450
+
30451
+ await this.createView(assert, sView, oModel);
30452
+
30453
+ const oTable = this.oView.byId("table");
30454
+ checkTable("initial page", assert, oTable, [
30455
+ "/EMPLOYEES('0')",
30456
+ "/EMPLOYEES('9')"
30457
+ ], [
30458
+ [false, 1, "0", "Alpha"],
30459
+ [undefined, 1, "9", "Omega"]
30460
+ ]);
30461
+ const oAlpha = oTable.getRows()[0].getBindingContext();
30462
+
30463
+ this.expectRequest("EMPLOYEES?$apply=descendants($root/EMPLOYEES,OrgChart,ID"
30464
+ + ",filter(ID eq '0'),1)"
30465
+ + "&$select=DrillState,ID,Name&$count=true&$skip=0&$top=2", {
30466
+ "@odata.count" : "4",
30467
+ value : [{
30468
+ DrillState : "leaf",
30469
+ ID : "1",
30470
+ Name : "Beta"
30471
+ }, {
30472
+ DrillState : "leaf",
30473
+ ID : "2",
30474
+ Name : "Gamma"
30475
+ }]
30476
+ })
30477
+ .expectChange("id", [, "1"]);
30478
+
30479
+ oAlpha.expand();
30480
+
30481
+ await this.waitForChanges(assert, "expand 0 (Alpha)");
30482
+
30483
+ checkTable("after expand 0 (Alpha)", assert, oTable, [
30484
+ "/EMPLOYEES('0')",
30485
+ "/EMPLOYEES('1')",
30486
+ "/EMPLOYEES('2')",
30487
+ "/EMPLOYEES('9')"
30488
+ ], [
30489
+ [true, 1, "0", "Alpha"],
30490
+ [undefined, 2, "1", "Beta"]
30491
+ ], 6);
30492
+
30493
+ this.expectRequest("EMPLOYEES?$apply=descendants($root/EMPLOYEES,OrgChart,ID"
30494
+ + ",filter(ID eq '0'),1)"
30495
+ + "&$select=DrillState,ID,Name&$skip=2&$top=2", {
30496
+ value : [{
30497
+ DrillState : "leaf",
30498
+ ID : "3",
30499
+ Name : "Delta"
30500
+ }, {
30501
+ DrillState : "leaf",
30502
+ ID : "4",
30503
+ Name : "Epsilon"
30504
+ }]
30505
+ })
30506
+ .expectChange("id", [,,, "3", "4"]);
30507
+
30508
+ oTable.setFirstVisibleRow(3); // scroll to "Delta"
30509
+
30510
+ await this.waitForChanges(assert, "setFirstVisibleRow to 3 (Delta)");
30511
+
30512
+ checkTable("after setFirstVisibleRow", assert, oTable, [
30513
+ "/EMPLOYEES('0')",
30514
+ "/EMPLOYEES('1')",
30515
+ "/EMPLOYEES('2')",
30516
+ "/EMPLOYEES('3')",
30517
+ "/EMPLOYEES('4')",
30518
+ "/EMPLOYEES('9')"
30519
+ ], [
30520
+ [undefined, 2, "3", "Delta"],
30521
+ [undefined, 2, "4", "Epsilon"]
30522
+ ]);
30523
+ const oDelta = oTable.getRows()[0].getBindingContext();
30524
+
30525
+ this.expectRequest("EMPLOYEES?$select=ID,Name&$filter=ID eq '3' or ID eq '4'"
30526
+ + "&$top=2", {
30527
+ value : [{
30528
+ DrillState : "leaf",
30529
+ ID : "3",
30530
+ Name : "Delta"
30531
+ }, {
30532
+ DrillState : "leaf",
30533
+ ID : "4",
30534
+ Name : "Epsilon"
30535
+ }]
30536
+ });
30537
+
30538
+ // code under test
30539
+ assert.strictEqual(oAlpha.getParent(), null);
30540
+ assert.strictEqual(await oAlpha.requestParent(), null);
30541
+
30542
+ await Promise.all([
30543
+ oDelta.getBinding().getHeaderContext().requestSideEffects(["Name"]),
30544
+ this.waitForChanges(assert, "request side effects for name")
30545
+ ]);
30546
+
30547
+ checkTable("after requestSideEffects", assert, oTable, [
30548
+ "/EMPLOYEES('3')",
30549
+ "/EMPLOYEES('4')"
30550
+ ], [
30551
+ [undefined, 2, "3", "Delta"],
30552
+ [undefined, 2, "4", "Epsilon"]
30553
+ ], 6);
30554
+
30555
+ // code under test
30556
+ assert.strictEqual(oDelta.getParent(), undefined, "JIRA: CPOUI5ODATAV4-2323");
30557
+
30558
+ this.expectRequest("EMPLOYEES?$apply=com.sap.vocabularies.Hierarchy.v1.TopLevels("
30559
+ + "HierarchyNodes=$root/EMPLOYEES,HierarchyQualifier='OrgChart'"
30560
+ + ",NodeProperty='ID',Levels=1)"
30561
+ + "&$select=DrillState,ID,Name&$skip=0&$top=1", {
30562
+ value : [{
30563
+ DrillState : "collapsed",
30564
+ ID : "0",
30565
+ Name : "Alpha"
30566
+ }]
30567
+ })
30568
+ .expectChange("id", ["0", "9"]);
30569
+
30570
+ // code under test
30571
+ const oResult = await oDelta.requestParent();
30572
+
30573
+ assert.strictEqual(oAlpha.getModel(), undefined, "Alpha is destroyed");
30574
+ assert.notStrictEqual(oResult, oAlpha);
30575
+ assert.strictEqual(oResult.getPath(), oAlpha.getPath());
30576
+ assert.strictEqual(oResult.iIndex, oAlpha.iIndex);
30577
+ assert.strictEqual(oDelta.getParent(), oResult,
30578
+ "#getParent and #requestParent must deliver the same context");
30579
+
30580
+ checkTable("after requestParent", assert, oTable, [
30581
+ "/EMPLOYEES('0')",
30582
+ "/EMPLOYEES('3')",
30583
+ "/EMPLOYEES('4')"
30584
+ ], [
30585
+ [undefined, 2, "3", "Delta"],
30586
+ [undefined, 2, "4", "Epsilon"]
30587
+ ], 6);
30588
+ });
30589
+
29106
30590
  //*********************************************************************************************
29107
30591
  // Scenario: Show the single root node of a recursive hierarchy and expand it. Not all children
29108
30592
  // are loaded, but some placeholders remain. Create two new child nodes underneath the root.
@@ -41432,7 +42916,7 @@ sap.ui.define([
41432
42916
  }
41433
42917
 
41434
42918
  // code under test
41435
- Configuration.setSecurityTokenHandlers([
42919
+ Security.setSecurityTokenHandlers([
41436
42920
  securityTokenHandler0,
41437
42921
  securityTokenHandler1,
41438
42922
  securityTokenHandler2
@@ -41456,7 +42940,7 @@ sap.ui.define([
41456
42940
 
41457
42941
  return that.waitForChanges(assert);
41458
42942
  }).finally(function () {
41459
- Configuration.setSecurityTokenHandlers([]);
42943
+ Security.setSecurityTokenHandlers([]);
41460
42944
  });
41461
42945
  });
41462
42946
  });
@@ -42292,7 +43776,8 @@ sap.ui.define([
42292
43776
  // BCP: 2080062941
42293
43777
  testXMLTemplating("BCP: 2080062941",
42294
43778
  "createSpecialCasesModel",
42295
- '<template:alias name="format" value="sap.ui.model.odata.v4.AnnotationHelper.format">\
43779
+ ' template:require="{\'AnnotationHelper\':\'sap/ui/model/odata/v4/AnnotationHelper\'}">\
43780
+ <template:alias name="format" value="AnnotationHelper.format">\
42296
43781
  <template:repeat \
42297
43782
  list="{meta>/special.cases.EntityWithUnsupportedEdmTypes/@com.sap.vocabularies.UI.v1.SelectionFields}"\
42298
43783
  var="field">\
@@ -43256,7 +44741,8 @@ sap.ui.define([
43256
44741
  // JIRA: CPOUI5ODATAV4-104
43257
44742
  testXMLTemplating("AnnotationHelper#value on properties",
43258
44743
  "createSpecialCasesModel",
43259
- '<template:alias name="value" value="sap.ui.model.odata.v4.AnnotationHelper.value">\
44744
+ ' template:require="{\'AnnotationHelper\':\'sap/ui/model/odata/v4/AnnotationHelper\'}">\
44745
+ <template:alias name="value" value="AnnotationHelper.value">\
43260
44746
  <Input value="{meta>/Artists/Name@@value}"/>\
43261
44747
  <Input value="{meta>/Artists/BestFriend/IsActiveEntity@@value}"/>\
43262
44748
  <Input value="{meta>/Artists/Address/ZIP@@value}"/>\
@@ -43275,7 +44761,8 @@ sap.ui.define([
43275
44761
  // JIRA: CPOUI5ODATAV4-104
43276
44762
  testXMLTemplating("AnnotationHelper#value inside path object",
43277
44763
  "createSpecialCasesModel",
43278
- '<template:alias name="value" value="sap.ui.model.odata.v4.AnnotationHelper.value">\
44764
+ ' template:require="{\'AnnotationHelper\':\'sap/ui/model/odata/v4/AnnotationHelper\'}">\
44765
+ <template:alias name="value" value="AnnotationHelper.value">\
43279
44766
  <Input value="{meta>/Artists/@com.sap.vocabularies.UI.v1.SelectionFields/0/$PropertyPath@@value}"/>\
43280
44767
  <Input value="{meta>/Artists/@com.sap.vocabularies.UI.v1.SelectionFields/1/$PropertyPath@@value}"/>\
43281
44768
  <Input value="{meta>/Artists/ArtistID@com.sap.vocabularies.Common.v1.Text/$Path@@value}"/>\
@@ -43296,7 +44783,8 @@ sap.ui.define([
43296
44783
  // JIRA: CPOUI5ODATAV4-104
43297
44784
  testXMLTemplating("AnnotationHelper#format on properties",
43298
44785
  "createSpecialCasesModel",
43299
- '<template:alias name="format" value="sap.ui.model.odata.v4.AnnotationHelper.format">\
44786
+ ' template:require="{\'AnnotationHelper\':\'sap/ui/model/odata/v4/AnnotationHelper\'}">\
44787
+ <template:alias name="format" value="AnnotationHelper.format">\
43300
44788
  <Input value="{meta>/Artists/Name@@format}"/>\
43301
44789
  <Input value="{meta>/Artists/BestFriend/IsActiveEntity@@format}"/>\
43302
44790
  <Input value="{meta>/Artists/Address/ZIP@@format}"/>\
@@ -43320,7 +44808,8 @@ sap.ui.define([
43320
44808
  // JIRA: CPOUI5ODATAV4-104
43321
44809
  testXMLTemplating("AnnotationHelper#format inside path object",
43322
44810
  "createSpecialCasesModel",
43323
- '<template:alias name="format" value="sap.ui.model.odata.v4.AnnotationHelper.format">\
44811
+ ' template:require="{\'AnnotationHelper\':\'sap/ui/model/odata/v4/AnnotationHelper\'}">\
44812
+ <template:alias name="format" value="AnnotationHelper.format">\
43324
44813
  <Input value="{meta>/Artists/@com.sap.vocabularies.UI.v1.SelectionFields/0/$PropertyPath@@format}"/>\
43325
44814
  <Input value="{meta>/Artists/@com.sap.vocabularies.UI.v1.SelectionFields/1/$PropertyPath@@format}"/>\
43326
44815
  <Input value="{meta>/Artists/ArtistID@com.sap.vocabularies.Common.v1.Text/$Path@@format}"/>\