@openui5/sap.ui.core 1.125.0 → 1.126.0

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 (462) hide show
  1. package/.eslintrc.json +4 -1
  2. package/.reuse/dep5 +4 -4
  3. package/THIRDPARTY.txt +6 -6
  4. package/package.json +1 -1
  5. package/src/jquery.sap.global.js +1 -1
  6. package/src/jquery.sap.properties.js +1 -1
  7. package/src/jquery.sap.resources.js +1 -1
  8. package/src/jquery.sap.script.js +1 -1
  9. package/src/jquery.sap.storage.js +3 -3
  10. package/src/sap/base/Event.js +1 -1
  11. package/src/sap/base/Eventing.js +1 -1
  12. package/src/sap/base/Log.js +0 -16
  13. package/src/sap/base/config.js +1 -1
  14. package/src/sap/base/i18n/LanguageTag.js +1 -1
  15. package/src/sap/base/i18n/date/TimezoneUtils.js +1 -1
  16. package/src/sap/base/util/ObjectPath.js +6 -6
  17. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  18. package/src/sap/base/util/restricted/_castArray.js +1 -1
  19. package/src/sap/base/util/restricted/_compact.js +1 -1
  20. package/src/sap/base/util/restricted/_curry.js +1 -1
  21. package/src/sap/base/util/restricted/_debounce.js +1 -1
  22. package/src/sap/base/util/restricted/_difference.js +1 -1
  23. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  24. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  25. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  26. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  27. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  28. package/src/sap/base/util/restricted/_flatten.js +1 -1
  29. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  30. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  31. package/src/sap/base/util/restricted/_intersection.js +1 -1
  32. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  33. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  34. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  35. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  36. package/src/sap/base/util/restricted/_isNil.js +1 -1
  37. package/src/sap/base/util/restricted/_max.js +1 -1
  38. package/src/sap/base/util/restricted/_merge.js +1 -1
  39. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  40. package/src/sap/base/util/restricted/_min.js +1 -1
  41. package/src/sap/base/util/restricted/_omit.js +1 -1
  42. package/src/sap/base/util/restricted/_pick.js +1 -1
  43. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  44. package/src/sap/base/util/restricted/_throttle.js +1 -1
  45. package/src/sap/base/util/restricted/_toArray.js +1 -1
  46. package/src/sap/base/util/restricted/_union.js +1 -1
  47. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  48. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  49. package/src/sap/base/util/restricted/_uniq.js +1 -1
  50. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  51. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  52. package/src/sap/base/util/restricted/_without.js +1 -1
  53. package/src/sap/base/util/restricted/_xor.js +1 -1
  54. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  55. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  56. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  57. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  58. package/src/sap/ui/Device.js +35 -10
  59. package/src/sap/ui/Global.js +6 -6
  60. package/src/sap/ui/base/Event.js +1 -1
  61. package/src/sap/ui/base/EventProvider.js +1 -1
  62. package/src/sap/ui/base/Interface.js +1 -1
  63. package/src/sap/ui/base/ManagedObject.js +16 -1
  64. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  65. package/src/sap/ui/base/Metadata.js +1 -1
  66. package/src/sap/ui/base/Object.js +1 -1
  67. package/src/sap/ui/base/ObjectPool.js +1 -1
  68. package/src/sap/ui/core/.library +1 -8
  69. package/src/sap/ui/core/BusyIndicator.js +1 -1
  70. package/src/sap/ui/core/Component.js +17 -3
  71. package/src/sap/ui/core/ComponentContainer.js +1 -1
  72. package/src/sap/ui/core/ComponentMetadata.js +1 -1
  73. package/src/sap/ui/core/ComponentSupport.js +1 -1
  74. package/src/sap/ui/core/Configuration.js +1 -1
  75. package/src/sap/ui/core/Control.js +1 -1
  76. package/src/sap/ui/core/Core.js +14 -5
  77. package/src/sap/ui/core/CustomData.js +1 -1
  78. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  79. package/src/sap/ui/core/Element.js +1 -1
  80. package/src/sap/ui/core/ElementMetadata.js +1 -1
  81. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  82. package/src/sap/ui/core/EventBus.js +1 -1
  83. package/src/sap/ui/core/Fragment.js +1 -1
  84. package/src/sap/ui/core/HTML.js +1 -1
  85. package/src/sap/ui/core/History.js +1 -1
  86. package/src/sap/ui/core/Icon.js +1 -1
  87. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  88. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  89. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  90. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  91. package/src/sap/ui/core/InvisibleText.js +1 -1
  92. package/src/sap/ui/core/Item.js +1 -1
  93. package/src/sap/ui/core/LabelEnablement.js +1 -1
  94. package/src/sap/ui/core/LayoutData.js +1 -1
  95. package/src/sap/ui/core/Lib.js +2 -2
  96. package/src/sap/ui/core/ListItem.js +1 -1
  97. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  98. package/src/sap/ui/core/Locale.js +1 -1
  99. package/src/sap/ui/core/LocaleData.js +148 -102
  100. package/src/sap/ui/core/Manifest.js +1 -1
  101. package/src/sap/ui/core/Message.js +1 -1
  102. package/src/sap/ui/core/RenderManager.js +1 -1
  103. package/src/sap/ui/core/Renderer.js +1 -1
  104. package/src/sap/ui/core/ResizeHandler.js +1 -1
  105. package/src/sap/ui/core/ScrollBar.js +1 -1
  106. package/src/sap/ui/core/SeparatorItem.js +1 -1
  107. package/src/sap/ui/core/Title.js +1 -1
  108. package/src/sap/ui/core/TooltipBase.js +1 -1
  109. package/src/sap/ui/core/UIArea.js +2 -2
  110. package/src/sap/ui/core/UIComponent.js +1 -1
  111. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  112. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  113. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  114. package/src/sap/ui/core/XMLComposite.js +1 -1
  115. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  116. package/src/sap/ui/core/boot.js +1 -6
  117. package/src/sap/ui/core/date/UI5Date.js +1 -1
  118. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  119. package/src/sap/ui/core/delegate/ScrollEnablement.js +2 -2
  120. package/src/sap/ui/core/dnd/DragAndDrop.js +151 -10
  121. package/src/sap/ui/core/dnd/DragDropBase.js +13 -2
  122. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  123. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  124. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  125. package/src/sap/ui/{model → core/fieldhelp}/FieldHelp.js +92 -65
  126. package/src/sap/ui/core/fieldhelp/FieldHelpUtil.js +62 -0
  127. package/src/sap/ui/core/format/FormatUtils.js +1 -1
  128. package/src/sap/ui/core/format/TimezoneUtil.js +1 -1
  129. package/src/sap/ui/core/getCompatibilityVersion.js +1 -1
  130. package/src/sap/ui/core/hyphenation/Hyphenation.js +2 -1
  131. package/src/sap/ui/core/library.js +49 -9
  132. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  133. package/src/sap/ui/core/message/Message.js +1 -1
  134. package/src/sap/ui/core/message/MessageManager.js +1 -1
  135. package/src/sap/ui/core/message/MessageParser.js +1 -1
  136. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  137. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  138. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  139. package/src/sap/ui/core/mvc/JSView.js +1 -1
  140. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  141. package/src/sap/ui/core/mvc/View.js +1 -1
  142. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  143. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  144. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  145. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  146. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  147. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  148. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  149. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  150. package/src/sap/ui/core/service/Service.js +1 -1
  151. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  152. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  153. package/src/sap/ui/core/support/Plugin.js +1 -1
  154. package/src/sap/ui/core/support/Support.js +1 -1
  155. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  156. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  157. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  158. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  159. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  160. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  161. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  162. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  163. package/src/sap/ui/core/support/trace/E2eTraceLib.js +1 -1
  164. package/src/sap/ui/core/themes/sap_hcb/base_BlindLayer.less +37 -0
  165. package/src/sap/ui/core/themes/sap_hcb/base_BrowserScrollbar.less +36 -0
  166. package/src/sap/ui/core/themes/sap_hcb/base_BusyIndicator.less +19 -0
  167. package/src/sap/ui/core/themes/sap_hcb/base_CommandShortcutHints.less +20 -0
  168. package/src/sap/ui/core/themes/sap_hcb/base_DragAndDrop.less +76 -0
  169. package/src/sap/ui/core/themes/sap_hcb/base_Icon.less +144 -0
  170. package/src/sap/ui/core/themes/sap_hcb/base_LocalBusyIndicator.less +292 -0
  171. package/src/sap/ui/core/themes/sap_hcb/base_SAP-icons.less +10 -0
  172. package/src/sap/ui/core/themes/sap_hcb/base_ScrollBar.less +20 -0
  173. package/src/sap/ui/core/themes/sap_hcb/base_Shadow.less +3 -0
  174. package/src/sap/ui/core/themes/sap_hcb/base_TechnicalInfo.less +157 -0
  175. package/src/sap/ui/core/themes/sap_hcb/base_View.less +12 -0
  176. package/src/sap/ui/core/themes/sap_hcb/base_media.less +36 -0
  177. package/src/sap/ui/core/themes/sap_hcb/base_parameterClasses.less +83 -0
  178. package/src/sap/ui/core/themes/sap_hcb/base_shared.less +340 -0
  179. package/src/sap/ui/core/themes/sap_hcb/library.source.less +27 -1
  180. package/src/sap/ui/core/theming/Parameters.js +68 -8
  181. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  182. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  183. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  184. package/src/sap/ui/core/tmpl/Template.js +1 -1
  185. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  186. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  187. package/src/sap/ui/core/util/Export.js +1 -1
  188. package/src/sap/ui/core/util/ExportCell.js +1 -1
  189. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  190. package/src/sap/ui/core/util/ExportRow.js +1 -1
  191. package/src/sap/ui/core/util/ExportType.js +1 -1
  192. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  193. package/src/sap/ui/core/util/File.js +1 -1
  194. package/src/sap/ui/core/util/LibraryInfo.js +2 -2
  195. package/src/sap/ui/core/util/MockServer.js +1 -2
  196. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  197. package/src/sap/ui/core/util/XMLPreprocessor.js +14 -15
  198. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  199. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  200. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  201. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  202. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  203. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  204. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  205. package/src/sap/ui/core/webc/WebComponent.js +1 -1
  206. package/src/sap/ui/core/webc/WebComponentMetadata.js +1 -1
  207. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  208. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  209. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  210. package/src/sap/ui/debug/ControlTree.js +1 -1
  211. package/src/sap/ui/debug/DebugEnv.js +1 -1
  212. package/src/sap/ui/debug/PropertyList.js +1 -1
  213. package/src/sap/ui/model/Binding.js +28 -0
  214. package/src/sap/ui/model/ClientModel.js +1 -1
  215. package/src/sap/ui/model/CompositeDataState.js +1 -1
  216. package/src/sap/ui/model/CompositeType.js +1 -1
  217. package/src/sap/ui/model/DataState.js +1 -1
  218. package/src/sap/ui/model/ManagedObjectBindingSupport.js +5 -0
  219. package/src/sap/ui/model/MetaModel.js +1 -1
  220. package/src/sap/ui/model/Model.js +1 -1
  221. package/src/sap/ui/model/SelectionModel.js +1 -1
  222. package/src/sap/ui/model/SimpleType.js +1 -1
  223. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  224. package/src/sap/ui/model/Type.js +1 -1
  225. package/src/sap/ui/model/base/ManagedObjectModel.js +12 -2
  226. package/src/sap/ui/model/json/JSONModel.js +16 -11
  227. package/src/sap/ui/model/message/MessageModel.js +1 -1
  228. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  229. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  230. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  231. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  232. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  233. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +7 -2
  234. package/src/sap/ui/model/odata/ODataUtils.js +22 -14
  235. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  236. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  237. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  238. package/src/sap/ui/model/odata/type/Date.js +1 -1
  239. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  240. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  241. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  242. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
  243. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  244. package/src/sap/ui/model/odata/type/Double.js +1 -1
  245. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  246. package/src/sap/ui/model/odata/type/Int.js +1 -1
  247. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  248. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  249. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  250. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  251. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  252. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  253. package/src/sap/ui/model/odata/type/Single.js +1 -1
  254. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  255. package/src/sap/ui/model/odata/type/String.js +1 -1
  256. package/src/sap/ui/model/odata/type/Time.js +1 -1
  257. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  258. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  259. package/src/sap/ui/model/odata/v2/Context.js +1 -1
  260. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  261. package/src/sap/ui/model/odata/v2/ODataModel.js +1 -1
  262. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +1 -1
  263. package/src/sap/ui/model/odata/v4/Context.js +92 -43
  264. package/src/sap/ui/model/odata/v4/ODataBinding.js +20 -20
  265. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +6 -7
  266. package/src/sap/ui/model/odata/v4/ODataListBinding.js +176 -87
  267. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +9 -9
  268. package/src/sap/ui/model/odata/v4/ODataModel.js +36 -9
  269. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +3 -3
  270. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +12 -11
  271. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +176 -75
  272. package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +48 -9
  273. package/src/sap/ui/model/odata/v4/lib/_Cache.js +15 -17
  274. package/src/sap/ui/model/odata/v4/lib/_Helper.js +49 -14
  275. package/src/sap/ui/model/odata/v4/lib/_Parser.js +3 -3
  276. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +20 -12
  277. package/src/sap/ui/model/odata/v4/lib/_V2MetadataConverter.js +2 -2
  278. package/src/sap/ui/model/odata/v4/lib/_V2Requestor.js +3 -3
  279. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  280. package/src/sap/ui/model/type/Boolean.js +1 -1
  281. package/src/sap/ui/model/type/Currency.js +1 -1
  282. package/src/sap/ui/model/type/Date.js +1 -1
  283. package/src/sap/ui/model/type/DateInterval.js +1 -1
  284. package/src/sap/ui/model/type/DateTime.js +1 -1
  285. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  286. package/src/sap/ui/model/type/FileSize.js +1 -1
  287. package/src/sap/ui/model/type/Float.js +1 -1
  288. package/src/sap/ui/model/type/Integer.js +1 -1
  289. package/src/sap/ui/model/type/String.js +1 -1
  290. package/src/sap/ui/model/type/Time.js +1 -1
  291. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  292. package/src/sap/ui/model/type/Unit.js +1 -1
  293. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  294. package/src/sap/ui/performance/trace/FESR.js +2 -2
  295. package/src/sap/ui/performance/trace/Interaction.js +1 -1
  296. package/src/sap/ui/performance/trace/Passport.js +1 -1
  297. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  298. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  299. package/src/sap/ui/test/generic/TestBase.js +1 -1
  300. package/src/sap/ui/test/starter/_utils.js +18 -3
  301. package/src/sap/ui/util/Mobile.js +7 -4
  302. package/src/sap/ui/util/Storage.js +1 -1
  303. package/src/ui5loader-autoconfig.js +0 -25
  304. package/test/sap/ui/core/BindableResponseHeaders.html +1 -2
  305. package/test/sap/ui/core/ODataV2CanonicalRequests.html +8 -5
  306. package/test/sap/ui/core/ODataV2Messages.html +14 -11
  307. package/test/sap/ui/core/ODataV2MessagesPerf.html +34 -9
  308. package/test/sap/ui/core/demokit/sample/Messaging/ODataBackendMessagesComp/ui5.yaml +1 -1
  309. package/test/sap/ui/core/demokit/sample/OpaStartup/iStartMyAppInAFrame/iStartMyAppInAFrame.html +2 -1
  310. package/test/sap/ui/core/demokit/sample/OpaStartup/iStartMyAppInAFrame/iStartMyAppInAFrame.js +2 -12
  311. package/test/sap/ui/core/demokit/sample/common/Controller.js +2 -2
  312. package/test/sap/ui/core/demokit/sample/common/ValueHelp.js +2 -2
  313. package/test/sap/ui/core/demokit/sample/matcher/BindingPath/ui5.yaml +1 -1
  314. package/test/sap/ui/core/demokit/sample/matcher/Descendant/ui5.yaml +1 -1
  315. package/test/sap/ui/core/demokit/sample/matcher/I18NText/ui5.yaml +1 -1
  316. package/test/sap/ui/core/demokit/sample/matcher/LabelFor/ui5.yaml +1 -1
  317. package/test/sap/ui/core/demokit/sample/odata/v4/GridTable/SandboxModel.js +6 -6
  318. package/test/sap/ui/core/demokit/sample/odata/v4/HierarchyBindAction/Main.controller.js +110 -21
  319. package/test/sap/ui/core/demokit/sample/odata/v4/HierarchyBindAction/Main.view.xml +35 -43
  320. package/test/sap/ui/core/demokit/sample/odata/v4/RecursiveHierarchy/RecursiveHierarchy.controller.js +118 -26
  321. package/test/sap/ui/core/demokit/sample/odata/v4/RecursiveHierarchy/RecursiveHierarchy.view.xml +99 -90
  322. package/test/sap/ui/core/demokit/sample/odata/v4/RecursiveHierarchy/SandboxModel.js +87 -40
  323. package/test/sap/ui/core/demokit/sample/odata/v4/RecursiveHierarchy/pages/Main.js +4 -3
  324. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/Component.js +18 -0
  325. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/tests/CreateRelative.js +1 -8
  326. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersRTATest/Main.controller.js +1 -2
  327. package/test/sap/ui/core/demokit/tutorial/databinding/01/ui5.yaml +1 -1
  328. package/test/sap/ui/core/demokit/tutorial/databinding/02/ui5.yaml +1 -1
  329. package/test/sap/ui/core/demokit/tutorial/databinding/03/ui5.yaml +1 -1
  330. package/test/sap/ui/core/demokit/tutorial/databinding/04/ui5.yaml +1 -1
  331. package/test/sap/ui/core/demokit/tutorial/databinding/05/ui5.yaml +1 -1
  332. package/test/sap/ui/core/demokit/tutorial/databinding/06/ui5.yaml +1 -1
  333. package/test/sap/ui/core/demokit/tutorial/databinding/07/ui5.yaml +1 -1
  334. package/test/sap/ui/core/demokit/tutorial/databinding/08/ui5.yaml +1 -1
  335. package/test/sap/ui/core/demokit/tutorial/databinding/09/ui5.yaml +1 -1
  336. package/test/sap/ui/core/demokit/tutorial/databinding/10/ui5.yaml +1 -1
  337. package/test/sap/ui/core/demokit/tutorial/databinding/11/ui5.yaml +1 -1
  338. package/test/sap/ui/core/demokit/tutorial/databinding/12/ui5.yaml +1 -1
  339. package/test/sap/ui/core/demokit/tutorial/databinding/13/ui5.yaml +1 -1
  340. package/test/sap/ui/core/demokit/tutorial/databinding/14/ui5.yaml +1 -1
  341. package/test/sap/ui/core/demokit/tutorial/databinding/15/ui5.yaml +1 -1
  342. package/test/sap/ui/core/demokit/tutorial/mockserver/01/ui5.yaml +1 -1
  343. package/test/sap/ui/core/demokit/tutorial/mockserver/02/ui5.yaml +1 -1
  344. package/test/sap/ui/core/demokit/tutorial/mockserver/03/ui5.yaml +1 -1
  345. package/test/sap/ui/core/demokit/tutorial/mockserver/04/ui5.yaml +1 -1
  346. package/test/sap/ui/core/demokit/tutorial/navigation/01/ui5.yaml +1 -1
  347. package/test/sap/ui/core/demokit/tutorial/navigation/02/ui5.yaml +1 -1
  348. package/test/sap/ui/core/demokit/tutorial/navigation/03/ui5.yaml +1 -1
  349. package/test/sap/ui/core/demokit/tutorial/navigation/04/ui5.yaml +1 -1
  350. package/test/sap/ui/core/demokit/tutorial/navigation/05/ui5.yaml +1 -1
  351. package/test/sap/ui/core/demokit/tutorial/navigation/06/ui5.yaml +1 -1
  352. package/test/sap/ui/core/demokit/tutorial/navigation/07/ui5.yaml +1 -1
  353. package/test/sap/ui/core/demokit/tutorial/navigation/08/ui5.yaml +1 -1
  354. package/test/sap/ui/core/demokit/tutorial/navigation/09/ui5.yaml +1 -1
  355. package/test/sap/ui/core/demokit/tutorial/navigation/10/ui5.yaml +1 -1
  356. package/test/sap/ui/core/demokit/tutorial/navigation/11/ui5.yaml +1 -1
  357. package/test/sap/ui/core/demokit/tutorial/navigation/12/ui5.yaml +1 -1
  358. package/test/sap/ui/core/demokit/tutorial/navigation/13/ui5.yaml +1 -1
  359. package/test/sap/ui/core/demokit/tutorial/navigation/14/ui5.yaml +1 -1
  360. package/test/sap/ui/core/demokit/tutorial/navigation/15/ui5.yaml +1 -1
  361. package/test/sap/ui/core/demokit/tutorial/navigation/16/ui5.yaml +1 -1
  362. package/test/sap/ui/core/demokit/tutorial/navigation/17/ui5.yaml +1 -1
  363. package/test/sap/ui/core/demokit/tutorial/odatav4/01/ui5.yaml +1 -1
  364. package/test/sap/ui/core/demokit/tutorial/odatav4/01/webapp/localService/mockserver.js +4 -4
  365. package/test/sap/ui/core/demokit/tutorial/odatav4/02/ui5.yaml +1 -1
  366. package/test/sap/ui/core/demokit/tutorial/odatav4/02/webapp/localService/mockserver.js +4 -4
  367. package/test/sap/ui/core/demokit/tutorial/odatav4/03/ui5.yaml +1 -1
  368. package/test/sap/ui/core/demokit/tutorial/odatav4/03/webapp/localService/mockserver.js +4 -4
  369. package/test/sap/ui/core/demokit/tutorial/odatav4/04/ui5.yaml +1 -1
  370. package/test/sap/ui/core/demokit/tutorial/odatav4/04/webapp/localService/mockserver.js +4 -4
  371. package/test/sap/ui/core/demokit/tutorial/odatav4/05/ui5.yaml +1 -1
  372. package/test/sap/ui/core/demokit/tutorial/odatav4/05/webapp/localService/mockserver.js +4 -4
  373. package/test/sap/ui/core/demokit/tutorial/odatav4/06/ui5.yaml +1 -1
  374. package/test/sap/ui/core/demokit/tutorial/odatav4/06/webapp/localService/mockserver.js +4 -4
  375. package/test/sap/ui/core/demokit/tutorial/odatav4/07/ui5.yaml +1 -1
  376. package/test/sap/ui/core/demokit/tutorial/odatav4/07/webapp/localService/mockserver.js +4 -4
  377. package/test/sap/ui/core/demokit/tutorial/odatav4/08/ui5.yaml +1 -1
  378. package/test/sap/ui/core/demokit/tutorial/odatav4/08/webapp/localService/mockserver.js +4 -4
  379. package/test/sap/ui/core/demokit/tutorial/odatav4/09/ui5.yaml +1 -1
  380. package/test/sap/ui/core/demokit/tutorial/odatav4/09/webapp/localService/mockserver.js +4 -4
  381. package/test/sap/ui/core/demokit/tutorial/odatav4/10/ui5.yaml +1 -1
  382. package/test/sap/ui/core/demokit/tutorial/odatav4/10/webapp/localService/mockserver.js +4 -4
  383. package/test/sap/ui/core/demokit/tutorial/odatav4/11/ui5.yaml +1 -1
  384. package/test/sap/ui/core/demokit/tutorial/odatav4/11/webapp/localService/mockserver.js +4 -4
  385. package/test/sap/ui/core/demokit/tutorial/troubleshooting/01/ui5.yaml +1 -1
  386. package/test/sap/ui/core/internal/samples/odata/v2/TreeTable/Main.view.xml +3 -3
  387. package/test/sap/ui/core/qunit/CommandExecution.qunit.js +96 -92
  388. package/test/sap/ui/core/qunit/ManagedObjectModel.qunit.js +24 -0
  389. package/test/sap/ui/core/qunit/ThemeParameters.qunit.js +80 -0
  390. package/test/sap/ui/core/qunit/ThemeParameters_legacyAPIs.qunit.js +1 -0
  391. package/test/sap/ui/core/qunit/analytics/AnalyticalBinding.qunit.js +1 -1
  392. package/test/sap/ui/core/qunit/app/testsuite.app.qunit.js +2 -1
  393. package/test/sap/ui/core/qunit/base/Config.qunit.js +117 -114
  394. package/test/sap/ui/core/qunit/base/Config_bootstrap.qunit.html +3 -3
  395. package/test/sap/ui/core/qunit/base/Config_bootstrap.qunit.js +98 -95
  396. package/test/sap/ui/core/qunit/base/Config_cascade.qunit.js +20 -45
  397. package/test/sap/ui/core/qunit/base/Config_global.qunit.html +2 -2
  398. package/test/sap/ui/core/qunit/base/Config_meta.qunit.html +2 -2
  399. package/test/sap/ui/core/qunit/base/Config_noUrl.qunit.html +2 -2
  400. package/test/sap/ui/core/qunit/base/Config_noUrl.qunit.js +17 -16
  401. package/test/sap/ui/core/qunit/base/Config_url.qunit.html +2 -2
  402. package/test/sap/ui/core/qunit/bootstrap/BootstrapMainModule.beforeBootstrap.js +6 -0
  403. package/test/sap/ui/core/qunit/bootstrap/BootstrapMainModule.qunit.js +4 -4
  404. package/test/sap/ui/core/qunit/bootstrap/BootstrapMinimal.qunit.js +30 -10
  405. package/test/sap/ui/core/qunit/bootstrap/testsuite.bootstrap.qunit.js +5 -1
  406. package/test/sap/ui/core/qunit/dnd/DragAndDrop.qunit.js +159 -3
  407. package/test/sap/ui/core/qunit/{model → fieldhelp}/FieldHelp.qunit.js +306 -24
  408. package/test/sap/ui/core/qunit/fieldhelp/FieldHelpUtil.qunit.js +55 -0
  409. package/test/sap/ui/core/qunit/fieldhelp/testsuite.fieldhelp.qunit.html +12 -0
  410. package/test/sap/ui/core/qunit/fieldhelp/testsuite.fieldhelp.qunit.js +50 -0
  411. package/test/sap/ui/core/qunit/internal/1RingModels.qunit.html +1 -1
  412. package/test/sap/ui/core/qunit/internal/1RingModels.qunit.js +6 -1
  413. package/test/sap/ui/core/qunit/internal/testsuite.feature-odata-v4.qunit.js +1 -1
  414. package/test/sap/ui/core/qunit/jquery-mobile-custom.beforeBootstrap.js +11 -0
  415. package/test/sap/ui/core/qunit/jquery-mobile-custom.qunit.js +3 -3
  416. package/test/sap/ui/core/qunit/json/JSONModel.qunit.js +21 -0
  417. package/test/sap/ui/core/qunit/loader/asyncMode.qunit.js +2 -6
  418. package/test/sap/ui/core/qunit/loader/config.qunit.js +41 -2
  419. package/test/sap/ui/core/qunit/mvc/testsuite.mvc.qunit.js +9 -4
  420. package/test/sap/ui/core/qunit/odata/ODataUtils.qunit.js +5 -12
  421. package/test/sap/ui/core/qunit/odata/type/testsuite.odata.types.qunit.js +1 -0
  422. package/test/sap/ui/core/qunit/odata/v2/ODataModel.integration.qunit.js +202 -73
  423. package/test/sap/ui/core/qunit/odata/v2/ODataTreeBindingFlatNoFakeService.qunit.js +94 -2
  424. package/test/sap/ui/core/qunit/odata/v2/data/ZUI5_GWSAMPLE_BASIC.metadata.xml +4 -0
  425. package/test/sap/ui/core/qunit/odata/v4/Context.qunit.js +106 -103
  426. package/test/sap/ui/core/qunit/odata/v4/ODataBinding.qunit.js +3 -3
  427. package/test/sap/ui/core/qunit/odata/v4/ODataContextBinding.qunit.js +20 -20
  428. package/test/sap/ui/core/qunit/odata/v4/ODataListBinding.qunit.js +370 -109
  429. package/test/sap/ui/core/qunit/odata/v4/ODataMetaModel.qunit.js +42 -42
  430. package/test/sap/ui/core/qunit/odata/v4/ODataModel.integration.qunit.js +2260 -177
  431. package/test/sap/ui/core/qunit/odata/v4/ODataModel.qunit.js +39 -7
  432. package/test/sap/ui/core/qunit/odata/v4/ODataModel.realOData.qunit.js +7 -6
  433. package/test/sap/ui/core/qunit/odata/v4/ODataPropertyBinding.qunit.js +13 -14
  434. package/test/sap/ui/core/qunit/odata/v4/_AnnotationHelperExpression.qunit.js +3 -3
  435. package/test/sap/ui/core/qunit/odata/v4/lib/_AggregationCache.qunit.js +592 -169
  436. package/test/sap/ui/core/qunit/odata/v4/lib/_AggregationHelper.qunit.js +82 -2
  437. package/test/sap/ui/core/qunit/odata/v4/lib/_Cache.qunit.js +44 -47
  438. package/test/sap/ui/core/qunit/odata/v4/lib/_Helper.qunit.js +80 -20
  439. package/test/sap/ui/core/qunit/odata/v4/lib/_MetadataRequestor.qunit.js +2 -2
  440. package/test/sap/ui/core/qunit/odata/v4/lib/_Requestor.qunit.js +175 -69
  441. package/test/sap/ui/core/qunit/odata/v4/lib/_V2Requestor.qunit.js +3 -3
  442. package/test/sap/ui/core/qunit/odata/v4/testsuite.odatav4.qunit.js +1 -1
  443. package/test/sap/ui/core/qunit/performance/trace/FESR.qunit.js +9 -7
  444. package/test/sap/ui/core/qunit/rule/testsuite.rule.qunit.js +6 -1
  445. package/test/sap/ui/core/qunit/testdata/libraries/themeParameters/lib4/themes/sap_horizon_hcb/library.css +2 -0
  446. package/test/sap/ui/core/qunit/testsuite.qunit.js +1 -0
  447. package/test/sap/ui/core/qunit/testsuites/testsuite.browser.runtime.qunit.js +5 -1
  448. package/test/sap/ui/core/qunit/testsuites/testsuite.databinding.qunit.js +0 -3
  449. package/test/sap/ui/core/qunit/testsuites/testsuite.theming.qunit.js +4 -1
  450. package/test/sap/ui/core/qunit/ui/Device.qunit.js +68 -25
  451. package/test/sap/ui/core/qunit/ui5classes/ManagedObjectMetadata.qunit.js +3 -0
  452. package/test/sap/ui/core/qunit/util/Mobile.qunit.js +12 -7
  453. package/test/sap/ui/core/qunit/util/XMLPreprocessor.qunit.js +20 -20
  454. package/test/sap/ui/core/relnotes/changes-1.125.json +1 -6
  455. package/test/sap/ui/core/relnotes/changes-1.126.json +47 -0
  456. package/test/sap/ui/core/samples/databinding/UnitTable/ui5.yaml +1 -1
  457. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/firstItem-contextMenu.ref.lnk +1 -1
  458. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/initial.ref.lnk +1 -1
  459. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/lastItem-contextMenu.ref.lnk +1 -1
  460. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/leftDownBtn-contextMenu.ref.lnk +1 -1
  461. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/myButtonSample-contextMenu.ref.lnk +1 -1
  462. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/rightDownBtn-contextMenu.ref.lnk +1 -1
@@ -569,7 +569,7 @@ sap.ui.define([
569
569
  assert.strictEqual(oCache.oTreeState.sNodeProperty, "node/property");
570
570
  assert.strictEqual(oCache.bUnifiedCache, false);
571
571
 
572
- this.mock(oCache).expects("getTypes").returns("~types~");
572
+ this.mock(oCache).expects("getTypes").withExactArgs().returns("~types~");
573
573
  this.mock(_Helper).expects("getKeyFilter")
574
574
  .withExactArgs("~node~", "/resource/path", "~types~").returns("~filter~");
575
575
 
@@ -1084,7 +1084,7 @@ sap.ui.define([
1084
1084
  };
1085
1085
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, oAggregation);
1086
1086
  const sQueryOptions = JSON.stringify(oCache.mQueryOptions);
1087
- this.mock(oCache).expects("getTypes").atLeast(1).returns("~Types~");
1087
+ this.mock(oCache).expects("getTypes").atLeast(1).withExactArgs().returns("~Types~");
1088
1088
  const oNode = {"@$ui5.node.level" : 3};
1089
1089
  oCache.aElements[20] = {"@$ui5.node.level" : 0};
1090
1090
  oCache.aElements[21] = {"@$ui5.node.level" : 4};
@@ -1130,7 +1130,7 @@ sap.ui.define([
1130
1130
  .withExactArgs("~Parent~", "~Types~", "/Foo");
1131
1131
  this.mock(oCache).expects("findIndex").withExactArgs("~iRank~")
1132
1132
  .returns(17);
1133
- oHelperMock.expects("getPrivateAnnotation")
1133
+ oHelperMock.expects("hasPrivateAnnotation")
1134
1134
  .withExactArgs("~ParentInsideCollection~", "placeholder")
1135
1135
  .returns(bParentIsPlaceholder);
1136
1136
  this.mock(oCache).expects("insertNode")
@@ -1164,6 +1164,7 @@ sap.ui.define([
1164
1164
  assert.ok(oPromise instanceof SyncPromise);
1165
1165
  assert.strictEqual(await oPromise, 17);
1166
1166
  assert.strictEqual(JSON.stringify(oCache.mQueryOptions), sQueryOptions, "unchanged");
1167
+ oHelperMock.restore();
1167
1168
  assert.notOk(_Helper.hasPrivateAnnotation(oNode, "parentIndexPromise"), "gone");
1168
1169
  });
1169
1170
  });
@@ -1185,7 +1186,7 @@ sap.ui.define([
1185
1186
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, oAggregation);
1186
1187
  const sQueryOptions = JSON.stringify(oCache.mQueryOptions);
1187
1188
 
1188
- this.mock(oCache).expects("getTypes").atLeast(1).returns("~Types~");
1189
+ this.mock(oCache).expects("getTypes").atLeast(1).withExactArgs().returns("~Types~");
1189
1190
  const oNode = {};
1190
1191
  oCache.aElements[22] = {"@$ui5.node.level" : 0};
1191
1192
  oCache.aElements[23] = oNode;
@@ -1239,7 +1240,7 @@ sap.ui.define([
1239
1240
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, oAggregation);
1240
1241
  const sQueryOptions = JSON.stringify(oCache.mQueryOptions);
1241
1242
 
1242
- this.mock(oCache).expects("getTypes").returns("~Types~");
1243
+ this.mock(oCache).expects("getTypes").withExactArgs().returns("~Types~");
1243
1244
  const oNode = {};
1244
1245
  oCache.aElements[22] = {"@$ui5.node.level" : 0};
1245
1246
  oCache.aElements[23] = oNode;
@@ -1472,12 +1473,10 @@ sap.ui.define([
1472
1473
  that = this;
1473
1474
 
1474
1475
  function checkResult(oResult) {
1475
- var i;
1476
-
1477
1476
  assert.strictEqual(oResult.value.length, iLength);
1478
1477
  assert.strictEqual(oResult.value.$count, 42);
1479
- for (i = 0; i < iLength; i += 1) {
1480
- assert.strictEqual(oResult.value[i], "element#" + (oFixture.iIndex + i));
1478
+ for (let j = 0; j < iLength; j += 1) {
1479
+ assert.strictEqual(oResult.value[j], "element#" + (oFixture.iIndex + j));
1481
1480
  }
1482
1481
  }
1483
1482
 
@@ -1809,8 +1808,7 @@ sap.ui.define([
1809
1808
  iOffset = oFixture.bHasGrandTotal && oFixture.grandTotalAtBottomOnly !== true ? 1 : 0,
1810
1809
  oReadResult = {
1811
1810
  value : []
1812
- },
1813
- i;
1811
+ };
1814
1812
 
1815
1813
  if (oFixture.iExpandTo) { // unrealistic combination, but never mind
1816
1814
  oAggregation.expandTo = oFixture.iExpandTo;
@@ -1826,7 +1824,7 @@ sap.ui.define([
1826
1824
  _Helper.setPrivateAnnotation(oGrandTotal, "copy", oGrandTotalCopy);
1827
1825
  }
1828
1826
  oCache.oFirstLevel.bSentRequest = oFixture.bHasRequestedData;
1829
- for (i = 0; i < Math.min(iExpectedLength, 42); i += 1) {
1827
+ for (let j = 0; j < Math.min(iExpectedLength, 42); j += 1) {
1830
1828
  oReadResult.value.push({});
1831
1829
  }
1832
1830
  oReadResult.value.$count = 42;
@@ -1870,15 +1868,15 @@ sap.ui.define([
1870
1868
  sinon.match.same(oCache.oFirstLevel), iExpectedStart)
1871
1869
  .callsFake(addElements); // so that oCache.aElements is actually filled
1872
1870
  // expect placeholders before and after real read results
1873
- for (i = 0; i < iExpectedStart; i += 1) {
1871
+ for (let j = 0; j < iExpectedStart; j += 1) {
1874
1872
  oAggregationHelperMock.expects("createPlaceholder")
1875
- .withExactArgs(iExpectedLevel, i, sinon.match.same(oCache.oFirstLevel))
1876
- .returns("~placeholder~" + i);
1873
+ .withExactArgs(iExpectedLevel, j, sinon.match.same(oCache.oFirstLevel))
1874
+ .returns("~placeholder~" + j);
1877
1875
  }
1878
- for (i = iExpectedStart + iExpectedLength; i < 42; i += 1) {
1876
+ for (let j = iExpectedStart + iExpectedLength; j < 42; j += 1) {
1879
1877
  oAggregationHelperMock.expects("createPlaceholder")
1880
- .withExactArgs(iExpectedLevel, i, sinon.match.same(oCache.oFirstLevel))
1881
- .returns("~placeholder~" + i);
1878
+ .withExactArgs(iExpectedLevel, j, sinon.match.same(oCache.oFirstLevel))
1879
+ .returns("~placeholder~" + j);
1882
1880
  }
1883
1881
  const oHandleOutOfPlaceNodesExpectation = this.mock(oCache).expects("handleOutOfPlaceNodes")
1884
1882
  .withExactArgs(oFixture.bHasRequestedData
@@ -1891,11 +1889,11 @@ sap.ui.define([
1891
1889
  oFixture.iPrefetchLength ?? 20, "~oGroupLock~", "~fnDataRequested~")
1892
1890
  .then(function () {
1893
1891
  // check placeholders before and after real read results
1894
- for (i = 0; i < iExpectedStart; i += 1) {
1895
- assert.strictEqual(oCache.aElements[iOffset + i], "~placeholder~" + i);
1892
+ for (let j = 0; j < iExpectedStart; j += 1) {
1893
+ assert.strictEqual(oCache.aElements[iOffset + j], "~placeholder~" + j);
1896
1894
  }
1897
- for (i = iExpectedStart + iExpectedLength; i < 42; i += 1) {
1898
- assert.strictEqual(oCache.aElements[iOffset + i], "~placeholder~" + i);
1895
+ for (let j = iExpectedStart + iExpectedLength; j < 42; j += 1) {
1896
+ assert.strictEqual(oCache.aElements[iOffset + j], "~placeholder~" + j);
1899
1897
  }
1900
1898
 
1901
1899
  if (oFixture.bHasGrandTotal) {
@@ -3204,14 +3202,24 @@ sap.ui.define([
3204
3202
  //*********************************************************************************************
3205
3203
  [false, true].forEach(function (bUntilEnd) { // whether the collapsed children span until the end
3206
3204
  [undefined, false, true].forEach(function (bSubtotalsAtBottomOnly) {
3207
- var bSubtotalsAtBottom = bSubtotalsAtBottomOnly !== undefined,
3208
- sTitle = "collapse: until end = " + bUntilEnd
3209
- + ", subtotalsAtBottomOnly = " + bSubtotalsAtBottomOnly;
3205
+ [false, true].forEach(function (bRecursiveHierarchy) {
3206
+ const bSubtotalsAtBottom = bSubtotalsAtBottomOnly !== undefined;
3207
+ const sTitle = `collapse: until end = ${bUntilEnd},
3208
+ subtotalsAtBottomOnly = ${bSubtotalsAtBottomOnly},
3209
+ recursiveHierarchy = ${bRecursiveHierarchy}`;
3210
+
3211
+ if (bSubtotalsAtBottom && bRecursiveHierarchy) {
3212
+ return;
3213
+ }
3210
3214
 
3211
3215
  QUnit.test(sTitle, function (assert) {
3212
- var oAggregation = {
3213
- hierarchyQualifier : "X"
3214
- },
3216
+ var oAggregation = bRecursiveHierarchy
3217
+ ? {hierarchyQualifier : "X"}
3218
+ : { // filled before by buildApply
3219
+ aggregate : {},
3220
+ group : {},
3221
+ groupLevels : ["foo"]
3222
+ },
3215
3223
  oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation),
3216
3224
  bCollapseBottom = bUntilEnd || bSubtotalsAtBottom, // whether bottom line is affected
3217
3225
  oCollapsed = {
@@ -3232,7 +3240,11 @@ sap.ui.define([
3232
3240
  }, {
3233
3241
  "@$ui5._" : {predicate : "('3')"}
3234
3242
  }, {
3235
- "@$ui5._" : {predicate : "('4')"}
3243
+ // element kept in $byPredicate if recursive hierarchy
3244
+ "@$ui5._" : {predicate : "('4')", transientPredicate : "($uid=1-234)"},
3245
+ "@$ui5.context.isSelected" : true
3246
+ }, {
3247
+ "@$ui5._" : {predicate : "('5')"}
3236
3248
  // Note: for bSubtotalsAtBottom, this represents the extra row for subtotals
3237
3249
  }],
3238
3250
  aExpectedElements = [{
@@ -3241,14 +3253,14 @@ sap.ui.define([
3241
3253
  "@$ui5._" : {
3242
3254
  collapsed : oCollapsed,
3243
3255
  predicate : "('1')",
3244
- spliced : [aElements[2], aElements[3], aElements[4]],
3256
+ spliced : [aElements[2], aElements[3], aElements[4], aElements[5]],
3245
3257
  rank : "~rank~"
3246
3258
  },
3247
3259
  "@$ui5.node.isExpanded" : false,
3248
3260
  "@$ui5.node.level" : "~level~",
3249
3261
  A : "10" // placeholder for an aggregate with subtotals
3250
3262
  }, {
3251
- "@$ui5._" : {predicate : "('4')"}
3263
+ "@$ui5._" : {predicate : "('5')"}
3252
3264
  }];
3253
3265
 
3254
3266
  if (bSubtotalsAtBottom) {
@@ -3267,7 +3279,9 @@ sap.ui.define([
3267
3279
  "('2')" : aElements[2],
3268
3280
  "($uid=1-23)" : aElements[2],
3269
3281
  "('3')" : aElements[3],
3270
- "('4')" : aElements[4]
3282
+ "('4')" : aElements[4],
3283
+ "($uid=1-234)" : aElements[4],
3284
+ "('5')" : aElements[5]
3271
3285
  };
3272
3286
  this.mock(oCache).expects("getValue").withExactArgs("~path~").returns(aElements[1]);
3273
3287
  this.mock(_Helper).expects("updateAll")
@@ -3275,12 +3289,12 @@ sap.ui.define([
3275
3289
  sinon.match.same(aElements[1]), sinon.match.same(oCollapsed))
3276
3290
  .callThrough();
3277
3291
  this.mock(oCache).expects("countDescendants")
3278
- .withExactArgs(sinon.match.same(aElements[1]), 1).returns(bUntilEnd ? 3 : 2);
3292
+ .withExactArgs(sinon.match.same(aElements[1]), 1).returns(bUntilEnd ? 4 : 3);
3279
3293
  this.mock(oCache.oTreeState).expects("collapse")
3280
3294
  .withExactArgs(sinon.match.same(aElements[1]));
3281
3295
 
3282
3296
  // code under test
3283
- assert.strictEqual(oCache.collapse("~path~"), bCollapseBottom ? 3 : 2,
3297
+ assert.strictEqual(oCache.collapse("~path~"), bCollapseBottom ? 4 : 3,
3284
3298
  "number of removed elements");
3285
3299
 
3286
3300
  if (bCollapseBottom) { // last element was also a child, not a sibling
@@ -3291,28 +3305,48 @@ sap.ui.define([
3291
3305
  assert.deepEqual(oCache.aElements, aExpectedElements);
3292
3306
  assert.strictEqual(oCache.aElements[0], aElements[0]);
3293
3307
  assert.strictEqual(oCache.aElements[1], aElements[1]);
3294
- assert.strictEqual(oCache.aElements[2], bCollapseBottom ? undefined : aElements[4]);
3308
+ assert.strictEqual(oCache.aElements[2], bCollapseBottom ? undefined : aElements[5]);
3295
3309
  assert.strictEqual(oCache.aElements.$count, aExpectedElements.length);
3296
- assert.deepEqual(oCache.aElements.$byPredicate, bCollapseBottom
3297
- ? {
3298
- "('0')" : aElements[0],
3299
- "('1')" : aElements[1]
3300
- } : {
3301
- "('0')" : aElements[0],
3302
- "('1')" : aElements[1],
3303
- "('4')" : aElements[4]
3304
- });
3310
+ if (bRecursiveHierarchy) {
3311
+ assert.deepEqual(oCache.aElements.$byPredicate, bCollapseBottom
3312
+ ? {
3313
+ "('0')" : aElements[0],
3314
+ "('1')" : aElements[1],
3315
+ "('4')" : aElements[4],
3316
+ "($uid=1-234)" : aElements[4]
3317
+ } : {
3318
+ "('0')" : aElements[0],
3319
+ "('1')" : aElements[1],
3320
+ "('4')" : aElements[4],
3321
+ "($uid=1-234)" : aElements[4],
3322
+ "('5')" : aElements[5]
3323
+ });
3324
+ } else {
3325
+ assert.deepEqual(oCache.aElements.$byPredicate, bCollapseBottom
3326
+ ? {
3327
+ "('0')" : aElements[0],
3328
+ "('1')" : aElements[1]
3329
+ } : {
3330
+ "('0')" : aElements[0],
3331
+ "('1')" : aElements[1],
3332
+ "('5')" : aElements[5]
3333
+ });
3334
+ }
3305
3335
  assert.strictEqual(aElements[1]["@$ui5._"].spliced.$level, "~level~");
3306
3336
  assert.strictEqual(aElements[1]["@$ui5._"].spliced.$rank, "~rank~");
3307
3337
  });
3338
+ });
3308
3339
  });
3309
3340
  });
3310
3341
 
3311
3342
  //*********************************************************************************************
3312
- QUnit.test("countDescendants: until end", function (assert) {
3313
- const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
3314
- hierarchyQualifier : "X"
3315
- });
3343
+ [false, true].forEach(function (bHierarchy) {
3344
+ const oAggregation = bHierarchy
3345
+ ? {expandTo : 1, hierarchyQualifier : "X"}
3346
+ : {aggregate : {}, group : {}, groupLevels : ["foo"]};
3347
+
3348
+ QUnit.test(`countDescendants: until end, hierarchy=${bHierarchy}`, function (assert) {
3349
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation);
3316
3350
  // Note: the collapsed children span until the end
3317
3351
  oCache.aElements = [{
3318
3352
  // "@$ui5.node.level" : ignored
@@ -3332,9 +3366,32 @@ sap.ui.define([
3332
3366
  "number of removed elements");
3333
3367
  });
3334
3368
 
3369
+ QUnit.test(`countDescendants: single level cache, hierarchy=${bHierarchy}`, function (assert) {
3370
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation);
3371
+ oCache.aElements = [{
3372
+ // "@$ui5.node.level" : ignored
3373
+ }, {
3374
+ "@$ui5.node.isExpanded" : true,
3375
+ "@$ui5.node.level" : 5
3376
+ }, {
3377
+ "@$ui5.node.level" : 6 // child
3378
+ }, {
3379
+ "@$ui5.node.level" : 7 // grandchild
3380
+ }, {
3381
+ "@$ui5.node.level" : 6 // child
3382
+ }, {
3383
+ "@$ui5.node.level" : 5 // sibling
3384
+ }]; // simulate a read
3385
+
3386
+ // code under test
3387
+ assert.strictEqual(oCache.countDescendants(oCache.aElements[1], 1), 3,
3388
+ "number of removed elements");
3389
+ });
3390
+ });
3391
+
3335
3392
  //*********************************************************************************************
3336
3393
  [false, true].forEach(function (bUnifiedCache) {
3337
- const sTitle = "countDescendants: skip descendants of manually collapsed node, unified cache: "
3394
+ const sTitle = "countDescendants: skip descendants, unified cache: "
3338
3395
  + bUnifiedCache;
3339
3396
  QUnit.test(sTitle, function (assert) {
3340
3397
  const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
@@ -3345,29 +3402,44 @@ sap.ui.define([
3345
3402
  oCache.aElements = [{
3346
3403
  "@$ui5._" : {
3347
3404
  descendants : 41,
3348
- predicate : "('0')"
3405
+ predicate : "('0')",
3406
+ rank : "~" // the actual rank does not matter
3349
3407
  },
3350
3408
  "@$ui5.node.isExpanded" : true,
3351
3409
  "@$ui5.node.level" : 1
3352
3410
  }, {
3353
3411
  "@$ui5._" : {
3354
3412
  descendants : 40,
3355
- predicate : "('1')"
3413
+ predicate : "('1')",
3414
+ rank : "~" // the actual rank does not matter
3356
3415
  },
3357
3416
  "@$ui5.node.isExpanded" : true,
3358
3417
  "@$ui5.node.level" : 2
3359
3418
  }, {
3360
3419
  "@$ui5._" : {
3361
3420
  predicate : "('2')"
3421
+ // no rank
3422
+ },
3423
+ "@$ui5.node.isExpanded" : true,
3424
+ "@$ui5.node.level" : 2
3425
+ }, {
3426
+ "@$ui5._" : {
3427
+ predicate : "('3')",
3428
+ rank : "~" // the actual rank does not matter
3362
3429
  },
3363
3430
  "@$ui5.node.level" : 1
3364
3431
  }]; // simulate a read
3365
3432
  for (let i = 0; i < 40; i += 1) { // add 40 placeholders for descendants of ('1')
3366
- oCache.aElements.splice(2, 0, {"@$ui5.node.level" : 3});
3433
+ oCache.aElements.splice(2, 0, {
3434
+ "@$ui5._" : {
3435
+ rank : "~" // the actual rank does not matter
3436
+ },
3437
+ "@$ui5.node.level" : 3
3438
+ });
3367
3439
  }
3368
3440
 
3369
3441
  // code under test
3370
- assert.strictEqual(oCache.countDescendants(oCache.aElements[0], 0), 41,
3442
+ assert.strictEqual(oCache.countDescendants(oCache.aElements[0], 0), 42,
3371
3443
  "number of removed elements");
3372
3444
  });
3373
3445
  });
@@ -3384,19 +3456,29 @@ sap.ui.define([
3384
3456
  oCache.bUnifiedCache = bUnifiedCache;
3385
3457
  oCache.aElements = [{
3386
3458
  "@$ui5._" : {
3387
- descendants : 2
3459
+ descendants : 2,
3460
+ rank : "~" // the actual rank does not matter
3388
3461
  },
3389
3462
  "@$ui5.node.isExpanded" : true,
3390
3463
  "@$ui5.node.level" : 1
3391
3464
  }, {
3392
3465
  // no descendants at edge of top pyramid!
3466
+ "@$ui5._" : {
3467
+ rank : "~" // the actual rank does not matter
3468
+ },
3393
3469
  "@$ui5.node.isExpanded" : false,
3394
3470
  "@$ui5.node.level" : 2
3395
3471
  }, {
3396
3472
  // no descendants at edge of top pyramid!
3473
+ "@$ui5._" : {
3474
+ rank : "~" // the actual rank does not matter
3475
+ },
3397
3476
  "@$ui5.node.isExpanded" : false,
3398
3477
  "@$ui5.node.level" : 2
3399
3478
  }, {
3479
+ "@$ui5._" : {
3480
+ rank : "~" // the actual rank does not matter
3481
+ },
3400
3482
  "@$ui5.node.level" : 1
3401
3483
  }]; // simulate a read
3402
3484
 
@@ -3406,6 +3488,31 @@ sap.ui.define([
3406
3488
  });
3407
3489
  });
3408
3490
 
3491
+ //*********************************************************************************************
3492
+ QUnit.test("countDescendants: nodes w/o rank", function (assert) {
3493
+ const oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, {
3494
+ expandTo : 2,
3495
+ hierarchyQualifier : "X"
3496
+ });
3497
+ oCache.aElements = [{
3498
+ "@$ui5._" : {
3499
+ // no descendants since it is 0
3500
+ rank : "~" // the actual rank does not matter
3501
+ },
3502
+ "@$ui5.node.level" : 1
3503
+ }, {
3504
+ "@$ui5.node.level" : 2
3505
+ }, {
3506
+ "@$ui5.node.level" : 2
3507
+ }, {
3508
+ "@$ui5._" : {rank : "~"}, // the actual rank does not matter
3509
+ "@$ui5.node.level" : 1
3510
+ }]; // simulate a read
3511
+
3512
+ // code under test
3513
+ assert.strictEqual(oCache.countDescendants(oCache.aElements[0], 0), 2);
3514
+ });
3515
+
3409
3516
  //*********************************************************************************************
3410
3517
  QUnit.test("addElements", function (assert) {
3411
3518
  var oAggregation = { // filled before by buildApply
@@ -3731,12 +3838,14 @@ sap.ui.define([
3731
3838
  oCache = _AggregationCache.create(this.oRequestor, "~", "", {}, oAggregation);
3732
3839
 
3733
3840
  this.mock(oCache.oFirstLevel).expects("refreshKeptElements").on(oCache)
3734
- .withExactArgs("~oGroupLock~", "~fnOnRemove~", /*bDropApply*/true)
3841
+ .withExactArgs("~oGroupLock~", "~fnOnRemove~", "~bIgnorePendingChanges~",
3842
+ /*bDropApply*/true)
3735
3843
  .returns("~result~");
3736
3844
 
3737
3845
  assert.strictEqual(
3738
3846
  // code under test
3739
- oCache.refreshKeptElements("~oGroupLock~", "~fnOnRemove~", "~bDropApply~"),
3847
+ oCache.refreshKeptElements("~oGroupLock~", "~fnOnRemove~", "~bIgnorePendingChanges~",
3848
+ "~bDropApply~"),
3740
3849
  "~result~");
3741
3850
  });
3742
3851
 
@@ -4454,7 +4563,7 @@ sap.ui.define([
4454
4563
  .returns("A");
4455
4564
  self.mock(oCache).expects("requestRank").withExactArgs("~oChildNode~", "~oGroupLock~", true)
4456
4565
  .returns("C");
4457
- self.mock(SyncPromise).expects("all").withExactArgs(["A", undefined, "C"])
4566
+ self.mock(SyncPromise).expects("all").withExactArgs(["A", undefined, "C", undefined])
4458
4567
  .returns(SyncPromise.resolve([,, vRank]));
4459
4568
 
4460
4569
  const {promise : oSyncPromise, refresh : bRefresh}
@@ -4469,7 +4578,10 @@ sap.ui.define([
4469
4578
  .withExactArgs("~iRank~").returns("~findIndex~");
4470
4579
 
4471
4580
  // code under test
4472
- assert.strictEqual(fnGetRank(), vRank ? "~findIndex~" : undefined);
4581
+ assert.deepEqual(fnGetRank(), [
4582
+ vRank ? "~findIndex~" : undefined,
4583
+ undefined
4584
+ ]);
4473
4585
  }
4474
4586
 
4475
4587
  //*********************************************************************************************
@@ -4580,9 +4692,17 @@ sap.ui.define([
4580
4692
  });
4581
4693
 
4582
4694
  //*********************************************************************************************
4583
- [undefined, "~iRank~"].forEach((vRank, i) => {
4695
+ [undefined, "~iRank~"].forEach((vRank) => {
4584
4696
  [null, "Foo('43')"].forEach((sSiblingPath) => {
4585
- QUnit.test(`move: refresh needed (sibling=${sSiblingPath}) #${i}`, function (assert) {
4697
+ [false, true].forEach((bRequestSiblingRank) => {
4698
+ const sTitle = `move: refresh needed (rank=${vRank}, sibling=${sSiblingPath}`
4699
+ + `, request sibling rank=${bRequestSiblingRank})`;
4700
+
4701
+ if (bRequestSiblingRank && !sSiblingPath) {
4702
+ return;
4703
+ }
4704
+
4705
+ QUnit.test(sTitle, function (assert) {
4586
4706
  const oCache = _AggregationCache.create(this.oRequestor, "n/a", "", {}, {
4587
4707
  $Actions : {ChangeNextSiblingAction : "changeNextSibling"},
4588
4708
  $ParentNavigationProperty : "myParent",
@@ -4592,7 +4712,8 @@ sap.ui.define([
4592
4712
  });
4593
4713
  oCache.aElements.$byPredicate["('23')"] = "~oChildNode~";
4594
4714
  oCache.aElements.$byPredicate["('42')"] = {"@$ui5.node.isExpanded" : true}; // parent
4595
- oCache.aElements.$byPredicate["('43')"] = {foo : "A", bar : "B", baz : "C"}; // sibling
4715
+ const oSiblingNode = {foo : "A", bar : "B", baz : "C"};
4716
+ oCache.aElements.$byPredicate["('43')"] = oSiblingNode;
4596
4717
  const oTreeStateMock = this.mock(oCache.oTreeState);
4597
4718
  oTreeStateMock.expects("isOutOfPlace").withExactArgs("('23')").returns(false);
4598
4719
  oTreeStateMock.expects("isOutOfPlace").withExactArgs("('42')").returns(false);
@@ -4620,26 +4741,38 @@ sap.ui.define([
4620
4741
  Prefer : "return=minimal"
4621
4742
  }, {NextSibling : sSiblingPath ? {foo : "A", baz : "C"} : null})
4622
4743
  .returns("B");
4623
- this.mock(oCache).expects("requestRank")
4744
+ const oCacheMock = this.mock(oCache);
4745
+ oCacheMock.expects("requestRank")
4624
4746
  .withExactArgs("~oChildNode~", sinon.match.same(oGroupLock), true)
4625
4747
  .returns("C");
4626
- this.mock(SyncPromise).expects("all").withExactArgs(["A", "B", "C"])
4627
- .returns(SyncPromise.resolve([,, vRank]));
4748
+ oCacheMock.expects("requestRank").exactly(bRequestSiblingRank ? 1 : 0)
4749
+ .withExactArgs(sinon.match.same(oSiblingNode), sinon.match.same(oGroupLock), true)
4750
+ .returns("D");
4751
+ this.mock(SyncPromise).expects("all")
4752
+ .withExactArgs(["A", "B", "C", bRequestSiblingRank && "D"])
4753
+ .returns(SyncPromise.resolve([,, vRank, "~iSiblingRank~"]));
4628
4754
 
4629
4755
  const {promise : oSyncPromise, refresh : bRefresh}
4630
4756
  // code under test
4631
- = oCache.move(oGroupLock, "Foo('23')", "Foo('42')", sSiblingPath, "non/canonical");
4757
+ = oCache.move(oGroupLock, "Foo('23')", "Foo('42')", sSiblingPath, "non/canonical",
4758
+ bRequestSiblingRank);
4632
4759
 
4633
4760
  const fnGetRank = oSyncPromise.getResult();
4634
4761
  assert.strictEqual(typeof fnGetRank, "function");
4635
4762
  assert.strictEqual(bRefresh, true, "refresh needed");
4636
4763
 
4637
- this.mock(oCache).expects("findIndex").exactly(vRank ? 1 : 0)
4638
- .withExactArgs("~iRank~").returns("~findIndex~");
4764
+ oCacheMock.expects("findIndex").exactly(vRank ? 1 : 0)
4765
+ .withExactArgs("~iRank~").returns("~findIndex~child~");
4766
+ oCacheMock.expects("findIndex").exactly(bRequestSiblingRank ? 1 : 0)
4767
+ .withExactArgs("~iSiblingRank~").returns("~findIndex~sibling~");
4639
4768
 
4640
4769
  // code under test
4641
- assert.strictEqual(fnGetRank(), vRank ? "~findIndex~" : undefined);
4770
+ assert.deepEqual(fnGetRank(), [
4771
+ vRank ? "~findIndex~child~" : undefined,
4772
+ bRequestSiblingRank && "~findIndex~sibling~"
4773
+ ]);
4642
4774
  });
4775
+ });
4643
4776
  });
4644
4777
  });
4645
4778
 
@@ -4769,15 +4902,18 @@ sap.ui.define([
4769
4902
  [1, 2, 25].forEach(function (iExpandTo) {
4770
4903
  [undefined, true].forEach(function (bParentExpanded) {
4771
4904
  [false, true].forEach(function (bCreateRoot) {
4772
- var sTitle = "create: already has group level cache: " + bHasGroupLevelCache
4773
- + ", expandTo: " + iExpandTo
4774
- + ", parent's @$ui5.node.isExpanded: " + bParentExpanded
4775
- + ", create root node: " + bCreateRoot;
4776
-
4777
- const bInFirstLevel = bCreateRoot || iExpandTo > 24;
4778
- if (bHasGroupLevelCache && bInFirstLevel || bParentExpanded && bCreateRoot) {
4779
- return;
4780
- }
4905
+ [undefined, "~iRank~"].forEach(function (iRank) {
4906
+ var sTitle = "create: already has group level cache: " + bHasGroupLevelCache
4907
+ + ", expandTo: " + iExpandTo
4908
+ + ", parent's @$ui5.node.isExpanded: " + bParentExpanded
4909
+ + ", create root node: " + bCreateRoot
4910
+ + ", rank : " + iRank;
4911
+
4912
+ const bInFirstLevel = bCreateRoot || iExpandTo > 24;
4913
+ if (bHasGroupLevelCache && bInFirstLevel || bParentExpanded && bCreateRoot
4914
+ || !bInFirstLevel && !iRank) {
4915
+ return;
4916
+ }
4781
4917
 
4782
4918
  QUnit.test(sTitle, function (assert) {
4783
4919
  var fnCancelCallback,
@@ -4856,6 +4992,7 @@ sap.ui.define([
4856
4992
  .withExactArgs(sinon.match.same(oEntityData),
4857
4993
  bCreateRoot ? undefined : sinon.match.same(oParentNode));
4858
4994
  const iCallCount = bInFirstLevel && iExpandTo > 1 ? 1 : 0;
4995
+ const iRankCallCount = iCallCount && iRank ? 1 : 0;
4859
4996
  const oRankExpectation = that.mock(oCache).expects("requestRank")
4860
4997
  .exactly(iCallCount)
4861
4998
  .withExactArgs(sinon.match.same(oEntityData), "~oGroupLock~")
@@ -4865,7 +5002,7 @@ sap.ui.define([
4865
5002
  assert.ok(oRankExpectation
4866
5003
  .calledImmediatelyBefore(oNodeExpectation));
4867
5004
  });
4868
- return Promise.resolve("~iRank~");
5005
+ return Promise.resolve(iRank);
4869
5006
  });
4870
5007
  oNodeExpectation = that.mock(oCache).expects("requestNodeProperty")
4871
5008
  .withExactArgs(sinon.match.same(oEntityData), "~oGroupLock~", true)
@@ -4875,28 +5012,32 @@ sap.ui.define([
4875
5012
  resolve0();
4876
5013
  });
4877
5014
  }));
4878
- that.mock(oCache.oFirstLevel).expects("removeElement")
4879
- .exactly(iCallCount).withExactArgs(0, "~sTransientPredicate~");
5015
+ const oRemoveElementExpectation
5016
+ = that.mock(oCache.oFirstLevel).expects("removeElement")
5017
+ .exactly(iCallCount).withExactArgs(0);
4880
5018
  if (iCallCount) {
4881
5019
  // always done by #addElements, but needs to be undone in this case only
4882
5020
  oCache.aElements.$byPredicate["~sTransientPredicate~"] = "n/a";
4883
5021
  }
4884
5022
  const oDeleteTransientPredicateExpectation
4885
- = oHelperMock.expects("deletePrivateAnnotation")
4886
- .exactly(iCallCount)
5023
+ = oHelperMock.expects("deletePrivateAnnotation").exactly(iCallCount)
4887
5024
  .withExactArgs(sinon.match.same(oEntityData), "transientPredicate");
4888
- const oSetIndexExpectation
4889
- = oHelperMock.expects("setPrivateAnnotation").exactly(iCallCount)
4890
- .withExactArgs(sinon.match.same(oEntityData), "rank", "~iRank~");
4891
- that.mock(oCache.oFirstLevel).expects("restoreElement").exactly(iCallCount)
4892
- .withExactArgs("~iRank~", sinon.match.same(oEntityData))
5025
+ oCacheMock.expects("adjustDescendantCount").exactly(iRankCallCount)
5026
+ .withExactArgs(sinon.match.same(oEntityData), bCreateRoot ? 0 : 3, +1);
5027
+ const oSetRankExpectation = oHelperMock.expects("setPrivateAnnotation")
5028
+ .exactly(iRankCallCount)
5029
+ .withExactArgs(sinon.match.same(oEntityData), "rank", iRank);
5030
+ that.mock(oCache.oFirstLevel).expects("restoreElement")
5031
+ .exactly(iRankCallCount)
5032
+ .withExactArgs(iRank, sinon.match.same(oEntityData))
4893
5033
  .callsFake(function () {
5034
+ assert.ok(oRemoveElementExpectation.called);
4894
5035
  assert.ok(oDeleteTransientPredicateExpectation.called);
4895
5036
  });
4896
- that.mock(oCache).expects("shiftRank").exactly(iCallCount)
5037
+ that.mock(oCache).expects("shiftRank").exactly(iRankCallCount)
4897
5038
  .withExactArgs(bCreateRoot ? 0 : 3, +1)
4898
5039
  .callsFake(function () {
4899
- assert.ok(oSetIndexExpectation.called);
5040
+ assert.ok(oSetRankExpectation.called);
4900
5041
  });
4901
5042
  resolve();
4902
5043
  });
@@ -4912,16 +5053,13 @@ sap.ui.define([
4912
5053
  ? [null, "0", "1", "2", "3", "4"]
4913
5054
  : ["0", "1", oParentNode, null, "3", "4"]);
4914
5055
  });
4915
- const oAdjustDescendantCountExpectation = oCacheMock.expects("adjustDescendantCount")
4916
- .exactly(bInFirstLevel ? 1 : 0)
4917
- .withExactArgs(sinon.match.same(oEntityData), bCreateRoot ? 0 : 3, +1);
5056
+ oCacheMock.expects("adjustDescendantCount").never();
4918
5057
 
4919
5058
  // code under test
4920
5059
  const oResult = oCache.create("~oGroupLock~", "~oPostPathPromise~", "~sPath~",
4921
5060
  "~sTransientPredicate~", oEntityData, /*bAtEndOfCreated*/false, "~fnErrorCallback~",
4922
5061
  "~fnSubmitCallback~");
4923
5062
 
4924
- assert.strictEqual(oAdjustDescendantCountExpectation.callCount, bInFirstLevel ? 1 : 0);
4925
5063
  assert.deepEqual(oPostBody, bCreateRoot ? {} : {"myParent@odata.bind" : "~relativeUrl~"});
4926
5064
  assert.deepEqual(oEntityData, {
4927
5065
  "@$ui5._" : {postBody : oPostBody},
@@ -4952,8 +5090,6 @@ sap.ui.define([
4952
5090
  oHelperMock.expects("removeByPath")
4953
5091
  .withExactArgs(sinon.match.same(oCache.mPostRequests),
4954
5092
  "~sTransientPredicate~", sinon.match.same(oEntityData));
4955
- oCacheMock.expects("adjustDescendantCount").exactly(bInFirstLevel ? 1 : 0)
4956
- .withExactArgs(sinon.match.same(oEntityData), bCreateRoot ? 0 : 3, -1);
4957
5093
 
4958
5094
  // code under test
4959
5095
  fnCancelCallback();
@@ -4966,6 +5102,7 @@ sap.ui.define([
4966
5102
  assert.deepEqual(oCache.aElements, ["0", "1", oParentNode, "3", "4"]);
4967
5103
  });
4968
5104
  });
5105
+ });
4969
5106
  });
4970
5107
  });
4971
5108
  });
@@ -4973,15 +5110,17 @@ sap.ui.define([
4973
5110
 
4974
5111
  //*********************************************************************************************
4975
5112
  [undefined, 2].forEach(function (iRank) {
4976
- [undefined, true].forEach(function (bParentExpanded) {
4977
- [false, true].forEach(function (bCreateRoot) {
4978
- const sTitle = "create: createInPlace, rank: " + iRank
4979
- + ", parent's @$ui5.node.isExpanded: " + bParentExpanded
4980
- + ", create root node: " + bCreateRoot;
5113
+ [2, 25].forEach(function (iExpandTo) {
5114
+ [undefined, true].forEach(function (bParentExpanded) {
5115
+ [false, true].forEach(function (bCreateRoot) {
5116
+ const sTitle = "create: createInPlace, rank: " + iRank
5117
+ + ", expandTo: " + iExpandTo
5118
+ + ", parent's @$ui5.node.isExpanded: " + bParentExpanded
5119
+ + ", create root node: " + bCreateRoot;
4981
5120
 
4982
- if (bParentExpanded && bCreateRoot) {
4983
- return;
4984
- }
5121
+ if (bParentExpanded && bCreateRoot) {
5122
+ return;
5123
+ }
4985
5124
 
4986
5125
  QUnit.test(sTitle, function (assert) {
4987
5126
  var that = this;
@@ -4989,6 +5128,7 @@ sap.ui.define([
4989
5128
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
4990
5129
  $ParentNavigationProperty : "myParent",
4991
5130
  createInPlace : true,
5131
+ expandTo : iExpandTo,
4992
5132
  hierarchyQualifier : "X"
4993
5133
  });
4994
5134
  assert.strictEqual(oCache.bUnifiedCache, true, "activated by createInPlace");
@@ -5000,68 +5140,90 @@ sap.ui.define([
5000
5140
  oCache.aElements.$byPredicate = {"('42')" : oParentNode};
5001
5141
  oCache.aElements.$count = 3;
5002
5142
  this.mock(oCache).expects("createGroupLevelCache").never();
5003
- this.mock(oCache.oTreeState).expects("expand").never();
5143
+ this.mock(oCache.oTreeState).expects("setOutOfPlace").never();
5004
5144
  const oEntityData = {
5005
5145
  "@$ui5.node.parent" : (bCreateRoot ? undefined : "Foo('42')"),
5006
5146
  bar : "~bar~",
5007
5147
  foo : "~foo~"
5008
5148
  };
5009
- this.mock(_Helper).expects("addByPath")
5149
+ const oHelperMock = this.mock(_Helper);
5150
+ oHelperMock.expects("addByPath")
5010
5151
  .withExactArgs(sinon.match.same(oCache.mPostRequests), "~sTransientPredicate~",
5011
5152
  sinon.match.same(oEntityData));
5012
5153
  const oPostBody = {};
5154
+ const bExpandTreeState = !bParentExpanded && !bCreateRoot && iExpandTo < 23;
5155
+ let fnCancelCallback;
5013
5156
  this.mock(oCache.oFirstLevel).expects("create")
5014
5157
  .withExactArgs("~oGroupLock~", "~oPostPathPromise~", "~sPath~",
5015
5158
  "~sTransientPredicate~", {bar : "~bar~", foo : "~foo~"}, false, "~fnErrorCallback~",
5016
5159
  "~fnSubmitCallback~", sinon.match.func)
5017
5160
  .callsFake(function () {
5161
+ fnCancelCallback = arguments[8];
5018
5162
  _Helper.setPrivateAnnotation(oEntityData, "postBody", oPostBody);
5019
5163
  return new SyncPromise(function (resolve) {
5020
5164
  setTimeout(function () {
5021
- that.mock(oCache.oTreeState).expects("setOutOfPlace").never();
5022
- that.mock(_Helper).expects("removeByPath")
5165
+ _Helper.setPrivateAnnotation(oEntityData, "predicate", "('ABC')");
5166
+ oHelperMock.expects("removeByPath")
5023
5167
  .withExactArgs(sinon.match.same(oCache.mPostRequests),
5024
5168
  "~sTransientPredicate~", sinon.match.same(oEntityData));
5025
- that.mock(oCache).expects("requestRank")
5169
+ const oRequestRankExpectation = that.mock(oCache).expects("requestRank")
5026
5170
  .withExactArgs(sinon.match.same(oEntityData), "~oGroupLock~")
5027
5171
  .resolves(iRank);
5028
5172
  that.mock(oCache).expects("requestNodeProperty")
5029
5173
  .withExactArgs(sinon.match.same(oEntityData), "~oGroupLock~");
5030
- that.mock(oCache).expects("addElements").exactly(iRank ? 1 : 0)
5174
+ oHelperMock.expects("updateAll")
5175
+ .exactly(bParentExpanded || bCreateRoot || !iRank || bExpandTreeState
5176
+ ? 0 : 1)
5177
+ .withExactArgs(sinon.match.same(oCache.mChangeListeners), "('42')",
5178
+ sinon.match.same(oParentNode), {"@$ui5.node.isExpanded" : true})
5179
+ .callsFake(function () {
5180
+ assert.ok(oRequestRankExpectation.called);
5181
+ });
5182
+ that.mock(oCache).expects("addElements")
5183
+ .exactly(iRank && !bExpandTreeState ? 1 : 0)
5031
5184
  .withExactArgs(sinon.match.same(oEntityData), iRank,
5032
5185
  sinon.match.same(oCache.oFirstLevel), iRank)
5033
5186
  .callsFake(function () {
5034
5187
  assert.deepEqual(oCache.aElements, ["0", oParentNode, null, "2"]);
5035
5188
  });
5036
- that.mock(oCache).expects("adjustDescendantCount").exactly(iRank ? 1 : 0)
5189
+ that.mock(oCache).expects("adjustDescendantCount")
5190
+ .exactly(iRank && !bExpandTreeState ? 1 : 0)
5037
5191
  .withExactArgs(sinon.match.same(oEntityData), iRank, 1);
5038
5192
  that.mock(oCache.oFirstLevel).expects("removeElement")
5039
- .withExactArgs(0, "~sTransientPredicate~");
5040
- that.mock(_Helper).expects("deletePrivateAnnotation").exactly(iRank ? 1 : 0)
5193
+ .exactly(bExpandTreeState ? 0 : 1)
5194
+ .withExactArgs(0);
5195
+ oHelperMock.expects("deletePrivateAnnotation")
5196
+ .exactly(iRank && !bExpandTreeState ? 1 : 0)
5041
5197
  .withExactArgs(sinon.match.same(oEntityData), "transientPredicate");
5042
5198
  that.mock(oCache.oFirstLevel).expects("restoreElement")
5043
- .exactly(iRank ? 1 : 0)
5199
+ .exactly(iRank && !bExpandTreeState ? 1 : 0)
5044
5200
  .withExactArgs(iRank, sinon.match.same(oEntityData));
5045
- that.mock(oCache).expects("shiftRank").exactly(iRank ? 1 : 0)
5201
+ that.mock(oCache).expects("shiftRank")
5202
+ .exactly(iRank && !bExpandTreeState ? 1 : 0)
5046
5203
  .withExactArgs(iRank, +1);
5047
5204
  resolve();
5048
5205
  });
5049
5206
  });
5050
5207
  });
5051
- this.mock(_Helper).expects("makeRelativeUrl").exactly(bCreateRoot ? 0 : 1)
5208
+ oHelperMock.expects("makeRelativeUrl").exactly(bCreateRoot ? 0 : 1)
5052
5209
  .withExactArgs("/Foo('42')", "/Foo").returns("~relativeUrl~");
5210
+ const oExpandExpectation = this.mock(oCache.oTreeState).expects("expand")
5211
+ .exactly(bExpandTreeState ? 1 : 0)
5212
+ .withExactArgs(oParentNode);
5053
5213
 
5054
5214
  // code under test
5055
5215
  const oResult = oCache.create("~oGroupLock~", "~oPostPathPromise~", "~sPath~",
5056
5216
  "~sTransientPredicate~", oEntityData, /*bAtEndOfCreated*/false, "~fnErrorCallback~",
5057
5217
  "~fnSubmitCallback~");
5058
5218
 
5219
+ assert.strictEqual(oExpandExpectation.called, bExpandTreeState, "called synchronously");
5059
5220
  assert.deepEqual(oPostBody, bCreateRoot ? {} : {"myParent@odata.bind" : "~relativeUrl~"});
5060
- assert.deepEqual(oEntityData, {
5221
+ const oExpectedEntity = {
5061
5222
  "@$ui5._" : {postBody : oPostBody},
5062
5223
  bar : "~bar~",
5063
5224
  foo : "~foo~"
5064
- });
5225
+ };
5226
+ assert.deepEqual(oEntityData, oExpectedEntity);
5065
5227
  assert.strictEqual(oCache.aElements.$count, 3);
5066
5228
  assert.deepEqual(oCache.aElements.$byPredicate, {"('42')" : oParentNode});
5067
5229
  assert.deepEqual(oCache.aElements, ["0", oParentNode, "2"]);
@@ -5069,27 +5231,33 @@ sap.ui.define([
5069
5231
 
5070
5232
  return oResult.then(function (oEntityData0) {
5071
5233
  assert.strictEqual(oEntityData0, oEntityData);
5072
- if (iRank) {
5073
- assert.deepEqual(oEntityData, {
5074
- "@$ui5._" : {postBody : oPostBody, rank : iRank},
5075
- "@$ui5.node.level" : bCreateRoot ? 1 : 24,
5076
- bar : "~bar~",
5077
- foo : "~foo~"
5078
- });
5079
- assert.strictEqual(oCache.aElements.$count, 4);
5080
- } else {
5081
- assert.deepEqual(oEntityData, {
5082
- "@$ui5._" : {
5083
- postBody : oPostBody
5084
- },
5085
- bar : "~bar~",
5086
- foo : "~foo~"
5087
- });
5088
- assert.deepEqual(oCache.aElements, ["0", oParentNode, "2"]);
5089
- assert.strictEqual(oCache.aElements.$count, 3);
5234
+
5235
+ oExpectedEntity["@$ui5._"].predicate = "('ABC')";
5236
+ if (bExpandTreeState) {
5237
+ oExpectedEntity["@$ui5._"].rank = iRank;
5238
+ } else if (iRank) {
5239
+ oExpectedEntity["@$ui5._"].rank = iRank;
5240
+ oExpectedEntity["@$ui5.node.level"] = bCreateRoot ? 1 : 24;
5090
5241
  }
5242
+ assert.deepEqual(oEntityData, oExpectedEntity);
5243
+ const iExpectedCount = iRank && !bExpandTreeState ? 4 : 3;
5244
+ assert.strictEqual(oCache.aElements.$count, iExpectedCount);
5245
+ const aExpectedElements = iRank && !bExpandTreeState
5246
+ ? ["0", oParentNode, null, "2"] : ["0", oParentNode, "2"];
5247
+ assert.deepEqual(oCache.aElements, aExpectedElements);
5248
+
5249
+ oHelperMock.expects("removeByPath")
5250
+ .withExactArgs(sinon.match.same(oCache.mPostRequests),
5251
+ "~sTransientPredicate~", sinon.match.same(oEntityData));
5252
+
5253
+ // code under test
5254
+ fnCancelCallback();
5255
+
5256
+ assert.deepEqual(oCache.aElements, aExpectedElements, "unchanged");
5257
+ assert.strictEqual(oCache.aElements.$count, iExpectedCount, "unchanged");
5091
5258
  });
5092
5259
  });
5260
+ });
5093
5261
  });
5094
5262
  });
5095
5263
  });
@@ -5305,8 +5473,10 @@ sap.ui.define([
5305
5473
  [true, false].forEach((bInheritResult) => {
5306
5474
  [true, false].forEach((bDropFilter) => {
5307
5475
  [true, false].forEach((bRefreshNeeded) => {
5308
- const sTitle = "requestProperties: bInheritResult = " + bInheritResult
5309
- + ", bDropFilter = " + bDropFilter + ", bRefreshNeeded = " + bRefreshNeeded;
5476
+ [true, false].forEach((bEntityFound) => {
5477
+ const sTitle = "requestProperties: bInheritResult = " + bInheritResult
5478
+ + ", bDropFilter = " + bDropFilter + ", bRefreshNeeded = " + bRefreshNeeded
5479
+ + ", entity was found: " + bEntityFound;
5310
5480
 
5311
5481
  QUnit.test(sTitle, async function (assert) {
5312
5482
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
@@ -5380,24 +5550,23 @@ sap.ui.define([
5380
5550
  .resolves({
5381
5551
  "@odata.context" : "n/a",
5382
5552
  "@odata.metadataEtag" : "W/...",
5383
- value : ["~oResult~"]
5553
+ value : bEntityFound ? ["~oResult~"] : []
5384
5554
  });
5385
5555
 
5386
- if (bInheritResult) {
5387
- oHelperMock.expects("inheritPathValue")
5388
- .withExactArgs(["path", "to", "property0"], "~oResult~", "~oElement~", true);
5389
- oHelperMock.expects("inheritPathValue")
5390
- .withExactArgs(["path", "to", "property1"], "~oResult~", "~oElement~", true);
5391
- }
5556
+ oHelperMock.expects("inheritPathValue").exactly(bInheritResult && bEntityFound ? 1 : 0)
5557
+ .withExactArgs(["path", "to", "property0"], "~oResult~", "~oElement~", true);
5558
+ oHelperMock.expects("inheritPathValue").exactly(bInheritResult && bEntityFound ? 1 : 0)
5559
+ .withExactArgs(["path", "to", "property1"], "~oResult~", "~oElement~", true);
5392
5560
 
5393
5561
  assert.strictEqual(
5394
5562
  // code under test
5395
5563
  await oCache.requestProperties("~oElement~", aSelect, oGroupLock, bInheritResult,
5396
5564
  bDropFilter, bRefreshNeeded),
5397
- bInheritResult ? undefined : "~oResult~");
5565
+ bInheritResult || !bEntityFound ? undefined : "~oResult~");
5398
5566
 
5399
5567
  assert.strictEqual(oCache.oAggregation.$ExpandLevels, "~ExpandLevels~", "not overwritten");
5400
5568
  });
5569
+ });
5401
5570
  });
5402
5571
  });
5403
5572
  });
@@ -5994,22 +6163,24 @@ sap.ui.define([
5994
6163
  parent : oGroupLevel,
5995
6164
  rank : 0
5996
6165
  },
5997
- "@$ui5.node.level" : 1
6166
+ "@$ui5.node.level" : 2
5998
6167
  }, /*third level*/, {
5999
6168
  "@$ui5._" : {
6000
6169
  parent : oGroupLevel,
6001
6170
  rank : 1
6002
6171
  },
6003
- "@$ui5.node.level" : 1
6172
+ "@$ui5.node.level" : 2
6004
6173
  }, {
6005
6174
  "@$ui5._" : {
6006
6175
  parent : oGroupLevel,
6007
- rank : 2 // just a placeholder!
6176
+ placeholder : true,
6177
+ rank : 2
6008
6178
  },
6009
- "@$ui5.node.level" : 1
6179
+ "@$ui5.node.level" : 2
6010
6180
  }];
6011
6181
  oGroupLevel.aElements = [oCache.aElements[2], oCache.aElements[4]];
6012
6182
  oGroupLevel.aElements.$count = 3;
6183
+ this.mock(_AggregationHelper).expects("findPreviousSiblingIndex").never();
6013
6184
 
6014
6185
  oCacheMock.expects("findIndex").never();
6015
6186
 
@@ -6021,32 +6192,38 @@ sap.ui.define([
6021
6192
 
6022
6193
  oCacheMock.expects("findIndex").withExactArgs(1, sinon.match.same(oGroupLevel))
6023
6194
  .returns("A");
6195
+ oCache.aElements.A = {"@$ui5._" : {parent : oGroupLevel}};
6024
6196
 
6025
6197
  // code under test
6026
6198
  assert.strictEqual(oCache.getSiblingIndex(2, +1), "A");
6027
6199
 
6028
6200
  oCacheMock.expects("findIndex").withExactArgs(0, sinon.match.same(oGroupLevel))
6029
6201
  .returns("B");
6202
+ oCache.aElements.B = {"@$ui5._" : {parent : oGroupLevel}};
6030
6203
 
6031
6204
  // code under test
6032
6205
  assert.strictEqual(oCache.getSiblingIndex(4, -1), "B");
6033
6206
 
6034
- oCacheMock.expects("findIndex").withExactArgs(2, sinon.match.same(oGroupLevel))
6035
- .returns("C");
6207
+ oCacheMock.expects("findIndex").twice()
6208
+ .withExactArgs(2, sinon.match.same(oGroupLevel)).returns("C");
6209
+ oCache.aElements.C = {"@$ui5._" : {parent : oGroupLevel, placeholder : true}};
6036
6210
 
6037
6211
  // code under test
6038
- assert.strictEqual(oCache.getSiblingIndex(4, +1), "C");
6212
+ assert.strictEqual(oCache.getSiblingIndex(4, +1), undefined, "placeholder not allowed");
6213
+ assert.strictEqual(oCache.getSiblingIndex(4, +1, true), "C");
6039
6214
 
6040
6215
  oCacheMock.expects("findIndex").withExactArgs(1, sinon.match.same(oGroupLevel))
6041
6216
  .returns("D");
6217
+ oCache.aElements.D = {"@$ui5._" : {parent : oGroupLevel}};
6042
6218
 
6043
6219
  // code under test
6044
6220
  assert.strictEqual(oCache.getSiblingIndex(5, -1), "D");
6045
6221
  });
6046
6222
 
6047
6223
  //*********************************************************************************************
6048
- QUnit.test("getSiblingIndex: 1st level", function (assert) {
6224
+ QUnit.test("getSiblingIndex: 1st level, expandTo : 1", function (assert) {
6049
6225
  const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
6226
+ expandTo : 1, // @see _AggregationHlper.buildApply4Hierarchy
6050
6227
  hierarchyQualifier : "X"
6051
6228
  });
6052
6229
  const oCacheMock = this.mock(oCache);
@@ -6054,39 +6231,89 @@ sap.ui.define([
6054
6231
  oCache.aElements = [{
6055
6232
  "@$ui5._" : {
6056
6233
  parent : oFirstLevel,
6234
+ placeholder : true, // unrealistic, but more illustrative
6057
6235
  rank : 0
6058
6236
  },
6059
- "@$ui5.node.level" : 0
6237
+ "@$ui5.node.level" : 1
6060
6238
  }, {
6061
6239
  "@$ui5._" : {
6062
6240
  parent : oFirstLevel,
6241
+ placeholder : true, // unrealistic, but more illustrative
6063
6242
  rank : 1
6064
6243
  },
6065
- "@$ui5.node.level" : 0
6244
+ "@$ui5.node.level" : 1
6245
+ }];
6246
+ oFirstLevel.aElements = [oCache.aElements[0]];
6247
+ oFirstLevel.aElements.$count = oCache.aElements.length;
6248
+ oCache.oFirstLevel = oFirstLevel;
6249
+ this.mock(_AggregationHelper).expects("findPreviousSiblingIndex").never();
6250
+
6251
+ oCacheMock.expects("findIndex").never();
6252
+
6253
+ // code under test
6254
+ assert.strictEqual(oCache.getSiblingIndex(0, -1), -1);
6255
+
6256
+ oCacheMock.expects("findIndex").twice()
6257
+ .withExactArgs(1, sinon.match.same(oFirstLevel)).returns(1);
6258
+
6259
+ // code under test
6260
+ assert.strictEqual(oCache.getSiblingIndex(0, +1), undefined, "placeholder not allowed");
6261
+ assert.strictEqual(oCache.getSiblingIndex(0, +1, true), 1);
6262
+
6263
+ oCacheMock.expects("findIndex").twice()
6264
+ .withExactArgs(0, sinon.match.same(oFirstLevel)).returns(0);
6265
+
6266
+ // code under test
6267
+ assert.strictEqual(oCache.getSiblingIndex(1, -1), undefined, "placeholder not allowed");
6268
+ assert.strictEqual(oCache.getSiblingIndex(1, -1, true), 0);
6269
+ });
6270
+
6271
+ //*********************************************************************************************
6272
+ [false, true].forEach((bHasExpandLevels) => {
6273
+ const sTitle = "getSiblingIndex: 1st level, not a single level, next, has $ExpandLevels: "
6274
+ + bHasExpandLevels;
6275
+
6276
+ QUnit.test(sTitle, function (assert) {
6277
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
6278
+ $ExpandLevels : bHasExpandLevels ? "..." : undefined,
6279
+ expandTo : bHasExpandLevels ? 1 : 2,
6280
+ hierarchyQualifier : "X"
6281
+ });
6282
+ const oCacheMock = this.mock(oCache);
6283
+ const oFirstLevel = {};
6284
+ oCache.aElements = [{
6285
+ "@$ui5._" : {
6286
+ parent : oFirstLevel,
6287
+ rank : 0
6288
+ },
6289
+ "@$ui5.node.level" : 1
6066
6290
  }, {
6067
6291
  "@$ui5._" : {
6292
+ descendants : 1,
6068
6293
  parent : oFirstLevel,
6069
- rank : 2
6294
+ rank : 1
6070
6295
  },
6071
6296
  "@$ui5.node.level" : 1
6297
+ }, {
6298
+ "@$ui5._" : {
6299
+ parent : oFirstLevel,
6300
+ rank : 2
6301
+ },
6302
+ "@$ui5.node.level" : 2
6072
6303
  }, {
6073
6304
  "@$ui5._" : {
6074
6305
  parent : oFirstLevel,
6075
6306
  rank : 3
6076
6307
  },
6077
- "@$ui5.node.level" : 0
6308
+ "@$ui5.node.level" : 1
6078
6309
  }];
6079
6310
  oFirstLevel.aElements = oCache.aElements.slice(); // two arrays, but same elements!
6080
6311
  oFirstLevel.aElements.$count = oFirstLevel.aElements.length;
6312
+ oCache.oFirstLevel = oFirstLevel;
6313
+ this.mock(_AggregationHelper).expects("findPreviousSiblingIndex").never();
6081
6314
 
6082
6315
  oCacheMock.expects("findIndex").never();
6083
6316
 
6084
- // code under test
6085
- assert.strictEqual(oCache.getSiblingIndex(0, -1), -1);
6086
-
6087
- // code under test
6088
- assert.strictEqual(oCache.getSiblingIndex(2, -1), -1);
6089
-
6090
6317
  // code under test
6091
6318
  assert.strictEqual(oCache.getSiblingIndex(2, +1), -1);
6092
6319
 
@@ -6095,28 +6322,198 @@ sap.ui.define([
6095
6322
 
6096
6323
  oCacheMock.expects("findIndex").withExactArgs(1, sinon.match.same(oFirstLevel))
6097
6324
  .returns("A");
6325
+ oCache.aElements.A = {"@$ui5._" : {parent : oFirstLevel}};
6098
6326
 
6099
6327
  // code under test
6100
6328
  assert.strictEqual(oCache.getSiblingIndex(0, +1), "A");
6101
6329
 
6102
- oCacheMock.expects("findIndex").withExactArgs(0, sinon.match.same(oFirstLevel))
6330
+ oCacheMock.expects("findIndex").withExactArgs(3, sinon.match.same(oFirstLevel))
6103
6331
  .returns("B");
6332
+ oCache.aElements.B = {"@$ui5._" : {parent : oFirstLevel}};
6104
6333
 
6105
6334
  // code under test
6106
- assert.strictEqual(oCache.getSiblingIndex(1, -1), "B");
6335
+ assert.strictEqual(oCache.getSiblingIndex(1, +1), "B");
6107
6336
 
6108
6337
  oCacheMock.expects("findIndex").withExactArgs(3, sinon.match.same(oFirstLevel))
6109
6338
  .returns("C");
6339
+ oCache.aElements.C = {"@$ui5._" : {parent : oFirstLevel, placeholder : true}};
6110
6340
 
6111
6341
  // code under test
6112
- assert.strictEqual(oCache.getSiblingIndex(1, +1), "C");
6342
+ assert.strictEqual(oCache.getSiblingIndex(1, +1), undefined, "placeholder => cannot tell");
6343
+ });
6344
+ });
6113
6345
 
6114
- oCacheMock.expects("findIndex").withExactArgs(1, sinon.match.same(oFirstLevel))
6115
- .returns("D");
6346
+ //*********************************************************************************************
6347
+ [undefined, -1, 0, 1, 12].forEach((iResult) => {
6348
+ QUnit.test(`getSiblingIndex: findPreviousSiblingIndex=${iResult}`, function (assert) {
6349
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
6350
+ expandTo : 2,
6351
+ hierarchyQualifier : "X"
6352
+ });
6353
+ oCache.aElements[42] = { // oNode
6354
+ "@$ui5._" : {
6355
+ parent : oCache.oFirstLevel,
6356
+ rank : 23
6357
+ }
6358
+ };
6359
+ this.mock(_AggregationHelper).expects("findPreviousSiblingIndex")
6360
+ .withExactArgs(sinon.match.same(oCache.oFirstLevel.aElements), 23)
6361
+ .returns(iResult);
6362
+ this.mock(oCache).expects("findIndex").exactly(iResult >= 0 ? 1 : 0)
6363
+ .withExactArgs(iResult, sinon.match.same(oCache.oFirstLevel))
6364
+ .returns(17);
6365
+ oCache.aElements[17] = {}; // not a placeholder
6366
+
6367
+ assert.strictEqual(
6368
+ // code under test
6369
+ oCache.getSiblingIndex(42, -1),
6370
+ iResult >= 0 ? 17 : iResult
6371
+ );
6372
+ });
6373
+ });
6374
+
6375
+ //*********************************************************************************************
6376
+ QUnit.test("getSiblingIndex: no request for last", function (assert) {
6377
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
6378
+ // Note: expandTo > 1, but not really used here
6379
+ hierarchyQualifier : "X"
6380
+ });
6381
+ const oFirstLevel = {};
6382
+ // 0 Alpha (not loaded)
6383
+ // 1 Beta
6384
+ // 2 Gamma (not loaded)
6385
+ oCache.aElements = [{
6386
+ "@$ui5._" : {
6387
+ parent : oFirstLevel,
6388
+ placeholder : true,
6389
+ rank : 0
6390
+ },
6391
+ "@$ui5.node.level" : 0
6392
+ }, { // oNode: 1 (Beta)
6393
+ "@$ui5._" : {
6394
+ descendants : 1,
6395
+ parent : oFirstLevel,
6396
+ rank : 1
6397
+ },
6398
+ "@$ui5.node.level" : 2
6399
+ }, {
6400
+ "@$ui5._" : {
6401
+ parent : oFirstLevel,
6402
+ placeholder : true,
6403
+ rank : 2
6404
+ },
6405
+ "@$ui5.node.level" : 0
6406
+ }];
6407
+ oFirstLevel.aElements = [, oCache.aElements[1]];
6408
+ oFirstLevel.aElements.$count = oCache.aElements.length;
6409
+ // oCache.oFirstLevel = oFirstLevel; // does not matter here
6410
+
6411
+ this.mock(oCache).expects("findIndex").never();
6116
6412
 
6117
6413
  // code under test
6118
- assert.strictEqual(oCache.getSiblingIndex(3, -1), "D");
6414
+ assert.strictEqual(oCache.getSiblingIndex(1, +1), -1);
6415
+ });
6416
+
6417
+ //*********************************************************************************************
6418
+ [-1, 0, 1, 42].forEach((iSiblingIndex) => {
6419
+ QUnit.test(`requestSiblingIndex: no request for ${iSiblingIndex}`, async function (assert) {
6420
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
6421
+ // Note: expandTo not really used here
6422
+ hierarchyQualifier : "X"
6423
+ });
6424
+
6425
+ this.mock(oCache).expects("getSiblingIndex").withExactArgs("~iIndex~", "~iOffset~", true)
6426
+ .returns(iSiblingIndex);
6427
+
6428
+ assert.strictEqual(
6429
+ // code under test
6430
+ await oCache.requestSiblingIndex("~iIndex~", "~iOffset~", "~oGroupLock~"),
6431
+ iSiblingIndex);
6119
6432
  });
6433
+ });
6434
+
6435
+ //*********************************************************************************************
6436
+ [-1, +1].forEach((iOffset) => {
6437
+ [false, true].forEach((bWrongLevel) => {
6438
+ [false, true].forEach((bAlreadyIn) => {
6439
+ const sTitle = `requestSiblingIndex: request via 1st level, offset ${iOffset}`
6440
+ + `, wrong level: ${bWrongLevel}, already inside collection: ${bAlreadyIn}`;
6441
+
6442
+ QUnit.test(sTitle, async function (assert) {
6443
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo('42')", "", {}, {
6444
+ $DistanceFromRoot : "DistFromRoot",
6445
+ $LimitedRank : "Ltd_Rank",
6446
+ // Note: expandTo > 1, but not really used here
6447
+ hierarchyQualifier : "X"
6448
+ });
6449
+ const oFirstLevel = {
6450
+ calculateKeyPredicate : mustBeMocked,
6451
+ mQueryOptions : {
6452
+ foo : "~foo~",
6453
+ bar : "~bar~",
6454
+ $apply : "A.P.P.L.E.",
6455
+ $count : true,
6456
+ $select : ["a", "b", "c"]
6457
+ }
6458
+ };
6459
+ oCache.aElements = [{/*unused*/}, {/*unused*/}, { // oNode
6460
+ "@$ui5._" : {
6461
+ parent : oFirstLevel,
6462
+ rank : 2
6463
+ },
6464
+ "@$ui5.node.level" : 7 // unrealistic, but more illustrative
6465
+ }];
6466
+ oCache.aElements[42] = {};
6467
+ if (!bAlreadyIn) {
6468
+ oCache.aElements[42]["@$ui5._"] = {
6469
+ placeholder : true
6470
+ };
6471
+ }
6472
+ oCache.oFirstLevel = oFirstLevel;
6473
+ this.mock(oCache).expects("getSiblingIndex").withExactArgs(2, iOffset, true)
6474
+ .returns(undefined);
6475
+ const mExpectedQueryOptions = {
6476
+ foo : "~foo~",
6477
+ bar : "~bar~",
6478
+ $apply : "A.P.P.L.E.",
6479
+ $filter : iOffset < 0
6480
+ ? "Ltd_Rank lt 2 and DistFromRoot lt 7"
6481
+ : "Ltd_Rank gt 2 and DistFromRoot lt 7",
6482
+ $select : ["a", "b", "c", "Ltd_Rank"],
6483
+ $top : 1
6484
+ };
6485
+ if (iOffset < 0) {
6486
+ mExpectedQueryOptions.$orderby = "Ltd_Rank desc";
6487
+ }
6488
+ this.mock(this.oRequestor).expects("buildQueryString")
6489
+ .withExactArgs("", mExpectedQueryOptions, false, true, true).returns("?~sQuery~");
6490
+ const oSibling = {
6491
+ // Note: actually set by calculateKeyPredicate from DistanceFromRoot, but never mind
6492
+ "@$ui5.node.level" : bWrongLevel ? 8 : 7
6493
+ };
6494
+ this.mock(this.oRequestor).expects("request")
6495
+ .withExactArgs("GET", "Foo('42')?~sQuery~", "~oGroupLock~")
6496
+ .resolves({
6497
+ value : [oSibling, "n/a"]
6498
+ });
6499
+ this.mock(oCache).expects("getTypes").withExactArgs().returns("~Types~");
6500
+ this.mock(oFirstLevel).expects("calculateKeyPredicate")
6501
+ .withExactArgs(sinon.match.same(oSibling), "~Types~", "/Foo");
6502
+ this.mock(_Helper).expects("drillDown")
6503
+ .withExactArgs(sinon.match.same(oSibling), "Ltd_Rank").returns("42");
6504
+ this.mock(_Helper).expects("deleteProperty")
6505
+ .withExactArgs(sinon.match.same(oSibling), "Ltd_Rank");
6506
+ this.mock(oCache).expects("insertNode").exactly(bAlreadyIn ? 0 : 1)
6507
+ .withExactArgs(sinon.match.same(oSibling), 42);
6508
+
6509
+ assert.strictEqual(
6510
+ // code under test
6511
+ await oCache.requestSiblingIndex(2, iOffset, "~oGroupLock~"),
6512
+ bWrongLevel ? -1 : 42);
6513
+ });
6514
+ });
6515
+ });
6516
+ });
6120
6517
 
6121
6518
  //*********************************************************************************************
6122
6519
  QUnit.test("moveOutOfPlaceNodes: below parent", function (assert) {
@@ -6187,4 +6584,30 @@ sap.ui.define([
6187
6584
  // code under test
6188
6585
  oCache.resetOutOfPlace();
6189
6586
  });
6587
+
6588
+ //*********************************************************************************************
6589
+ [false, true].forEach(function (bCreateInPlace) {
6590
+ [undefined, false, true].forEach(function (bIsExpanded) {
6591
+ [2, 3, 4].forEach(function (iLevel) {
6592
+ const sTitle = "isRefreshNeededAfterCreate: createInPlace=" + bCreateInPlace
6593
+ + ", isExpanded=" + bIsExpanded + ", level=" + iLevel;
6594
+
6595
+ QUnit.test(sTitle, function (assert) {
6596
+ const oCache = _AggregationCache.create(this.oRequestor, "Foo", "", {}, {
6597
+ createInPlace : bCreateInPlace,
6598
+ expandTo : 3,
6599
+ hierarchyQualifier : "X"
6600
+ });
6601
+ oCache.aElements[42] = {
6602
+ "@$ui5.node.isExpanded" : bIsExpanded,
6603
+ "@$ui5.node.level" : iLevel
6604
+ };
6605
+
6606
+ // code under test
6607
+ assert.strictEqual(oCache.isRefreshNeededAfterCreate(42),
6608
+ bCreateInPlace && bIsExpanded === undefined && iLevel >= 3);
6609
+ });
6610
+ });
6611
+ });
6612
+ });
6190
6613
  });