dyo-tools 0.1.0 → 0.3.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 (184) hide show
  1. package/.c8rc.json +4 -0
  2. package/.eslintignore +2 -0
  3. package/.eslintrc.json +47 -0
  4. package/Makefile +34 -0
  5. package/README.md +0 -7
  6. package/babel.config.js +1 -0
  7. package/cucumber-report.html +48 -0
  8. package/dist/constants.d.ts +6 -0
  9. package/dist/constants.js +63 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/core/DTAction.d.ts +10 -0
  12. package/dist/core/DTAction.js +24 -0
  13. package/dist/core/DTAction.js.map +1 -0
  14. package/dist/core/DTBunch.d.ts +12 -17
  15. package/dist/core/DTBunch.js +39 -115
  16. package/dist/core/DTBunch.js.map +1 -1
  17. package/dist/core/DTComponent.d.ts +13 -5
  18. package/dist/core/DTComponent.js +39 -1
  19. package/dist/core/DTComponent.js.map +1 -1
  20. package/dist/core/DTComponentPhysical.d.ts +12 -0
  21. package/dist/core/DTComponentPhysical.js +22 -0
  22. package/dist/core/DTComponentPhysical.js.map +1 -0
  23. package/dist/core/DTComponentWithMeta.d.ts +2 -2
  24. package/dist/core/DTComponentWithMeta.js.map +1 -1
  25. package/dist/core/DTElement.d.ts +7 -7
  26. package/dist/core/DTElement.js +12 -11
  27. package/dist/core/DTElement.js.map +1 -1
  28. package/dist/core/DTManager.d.ts +33 -0
  29. package/dist/core/DTManager.js +190 -0
  30. package/dist/core/DTManager.js.map +1 -0
  31. package/dist/core/DTMaster.d.ts +24 -0
  32. package/dist/core/DTMaster.js +133 -0
  33. package/dist/core/DTMaster.js.map +1 -0
  34. package/dist/core/DTModule.d.ts +14 -0
  35. package/dist/core/DTModule.js +39 -0
  36. package/dist/core/DTModule.js.map +1 -0
  37. package/dist/index.d.ts +7 -1
  38. package/dist/index.js +15 -3
  39. package/dist/index.js.map +1 -1
  40. package/dist/libs/DYOFinder.d.ts +10 -0
  41. package/dist/libs/DYOFinder.js +96 -0
  42. package/dist/libs/DYOFinder.js.map +1 -0
  43. package/dist/libs/player/DTPlayer.element.d.ts +5 -0
  44. package/dist/libs/player/DTPlayer.element.js +11 -0
  45. package/dist/libs/player/DTPlayer.element.js.map +1 -0
  46. package/dist/libs/player/DTPlayer.manager.d.ts +11 -0
  47. package/dist/libs/player/DTPlayer.manager.js +42 -0
  48. package/dist/libs/player/DTPlayer.manager.js.map +1 -0
  49. package/dist/tsconfig.tsbuildinfo +1 -1321
  50. package/dist/types/core.d.ts +103 -0
  51. package/dist/types/core.js +15 -0
  52. package/dist/types/core.js.map +1 -0
  53. package/dist/types/index.d.ts +2 -58
  54. package/dist/types/index.js +16 -12
  55. package/dist/types/index.js.map +1 -1
  56. package/dist/types/player.d.ts +5 -0
  57. package/dist/types/player.js +3 -0
  58. package/dist/types/player.js.map +1 -0
  59. package/docs/.nojekyll +1 -0
  60. package/docs/assets/highlight.css +29 -0
  61. package/docs/assets/main.js +59 -0
  62. package/docs/assets/navigation.js +1 -0
  63. package/docs/assets/search.js +1 -0
  64. package/docs/assets/style.css +1414 -0
  65. package/docs/classes/core_DTAction.DYOToolsAction.html +89 -0
  66. package/docs/classes/core_DTBunch.DYOToolsBunch.html +254 -0
  67. package/docs/classes/core_DTComponent.DYOToolsComponent.html +76 -0
  68. package/docs/classes/core_DTComponentPhysical.DYOToolsComponentPhysical.html +110 -0
  69. package/docs/classes/core_DTComponentWithMeta.DYOToolsComponentWithMeta.html +96 -0
  70. package/docs/classes/core_DTElement.DYOToolsElement.html +135 -0
  71. package/docs/classes/core_DTError.DYOToolsError.html +37 -0
  72. package/docs/classes/core_DTManager.DYOToolsManager.html +237 -0
  73. package/docs/classes/core_DTMaster.DYOToolsMaster.html +150 -0
  74. package/docs/classes/core_DTModule.DYOToolsModule.html +92 -0
  75. package/docs/classes/libs_DYOFinder.DYOFinder.html +34 -0
  76. package/docs/classes/libs_player_DTPlayer_element.DYOToolsPlayer.html +134 -0
  77. package/docs/classes/libs_player_DTPlayer_manager.DYOToolsPlayerManager.html +243 -0
  78. package/docs/enums/types_core.FilterOperatorType.html +10 -0
  79. package/docs/hierarchy.html +1 -0
  80. package/docs/index.html +1 -0
  81. package/docs/interfaces/types_core.DTBunchFilters.html +6 -0
  82. package/docs/interfaces/types_core.DTBunchOptions.html +19 -0
  83. package/docs/interfaces/types_core.DTBunchToObject.html +7 -0
  84. package/docs/interfaces/types_core.DTComponentOptions.html +5 -0
  85. package/docs/interfaces/types_core.DTComponentToObject.html +4 -0
  86. package/docs/interfaces/types_core.DTElementToObject.html +7 -0
  87. package/docs/interfaces/types_core.DTManagerFilters.html +6 -0
  88. package/docs/interfaces/types_core.DTManagerOptions.html +8 -0
  89. package/docs/interfaces/types_core.DTManagerToObject.html +5 -0
  90. package/docs/interfaces/types_core.DTMasterToObject.html +8 -0
  91. package/docs/interfaces/types_core.DTModuleToObject.html +6 -0
  92. package/docs/interfaces/types_core.DYOFinderConfigurationPropDefault.html +4 -0
  93. package/docs/interfaces/types_core.DYOFinderConfigurationPropObjectSearch.html +4 -0
  94. package/docs/interfaces/types_core.DYOFinderFilterOperatorAdvanced.html +5 -0
  95. package/docs/interfaces/types_core.DYOFinderFilterOperatorBase.html +5 -0
  96. package/docs/interfaces/types_player.DTPlayerManagerSimpleConfiguration.html +3 -0
  97. package/docs/modules/constants.html +6 -0
  98. package/docs/modules/core_DTAction.html +2 -0
  99. package/docs/modules/core_DTBunch.html +2 -0
  100. package/docs/modules/core_DTComponent.html +2 -0
  101. package/docs/modules/core_DTComponentPhysical.html +2 -0
  102. package/docs/modules/core_DTComponentWithMeta.html +2 -0
  103. package/docs/modules/core_DTElement.html +2 -0
  104. package/docs/modules/core_DTError.html +2 -0
  105. package/docs/modules/core_DTManager.html +2 -0
  106. package/docs/modules/core_DTMaster.html +2 -0
  107. package/docs/modules/core_DTModule.html +2 -0
  108. package/docs/modules/libs_DYOFinder.html +2 -0
  109. package/docs/modules/libs_player_DTPlayer_element.html +2 -0
  110. package/docs/modules/libs_player_DTPlayer_manager.html +2 -0
  111. package/docs/modules/types.html +29 -0
  112. package/docs/modules/types_core.html +28 -0
  113. package/docs/modules/types_player.html +2 -0
  114. package/docs/types/types_core.DTAcceptedMetaData.html +2 -0
  115. package/docs/types/types_core.DTManagerItemType.html +1 -0
  116. package/docs/types/types_core.DTManagerItemsType.html +2 -0
  117. package/docs/types/types_core.DYOFinderComponentType.html +1 -0
  118. package/docs/types/types_core.DYOFinderConfiguration.html +2 -0
  119. package/docs/types/types_core.DYOFinderConfigurationProp.html +1 -0
  120. package/docs/types/types_core.DYOFinderFilterOperator.html +1 -0
  121. package/docs/types/types_core.DYOFinderFilterOperatorArgument.html +1 -0
  122. package/docs/types/types_core.DYOFinderFilters.html +1 -0
  123. package/docs/types/types_core.StandardPrimitiveType.html +2 -0
  124. package/docs/types/types_core.StandardPrimitiveTypeWithArray.html +1 -0
  125. package/docs/variables/constants.bunchDefaultOptions.html +2 -0
  126. package/docs/variables/constants.componentBunchDefaultFinderConfiguration.html +1 -0
  127. package/docs/variables/constants.componentManagerDefaultFinderConfiguration.html +1 -0
  128. package/docs/variables/constants.componentPhysicalDefaultFinderConfiguration.html +1 -0
  129. package/docs/variables/constants.managerDefaultOptions.html +2 -0
  130. package/jest.config.js +6 -0
  131. package/package.json +32 -23
  132. package/src/constants.ts +85 -0
  133. package/src/core/DTAction.ts +52 -0
  134. package/src/core/DTBunch.ts +467 -0
  135. package/src/core/DTComponent.ts +225 -0
  136. package/src/core/DTComponentPhysical.ts +53 -0
  137. package/src/core/DTComponentWithMeta.ts +65 -0
  138. package/src/core/DTElement.ts +102 -0
  139. package/src/core/DTError.ts +78 -0
  140. package/src/core/DTManager.ts +465 -0
  141. package/src/core/DTMaster.ts +318 -0
  142. package/src/core/DTModule.ts +90 -0
  143. package/src/index.ts +17 -0
  144. package/src/libs/DYOFinder.ts +175 -0
  145. package/src/libs/player/DTPlayer.element.ts +9 -0
  146. package/src/libs/player/DTPlayer.manager.ts +84 -0
  147. package/src/types/core.ts +169 -0
  148. package/src/types/index.ts +2 -0
  149. package/src/types/player.ts +6 -0
  150. package/test/core/DTAction.double.ts +78 -0
  151. package/test/core/DTAction.spec.ts +76 -0
  152. package/test/core/DTBunch.double.ts +261 -0
  153. package/test/core/DTBunch.spec.ts +897 -0
  154. package/test/core/DTComponent.double.ts +164 -0
  155. package/test/core/DTComponent.spec.ts +295 -0
  156. package/test/core/DTComponentPhysical.double.ts +76 -0
  157. package/test/core/DTComponentPhysical.spec.ts +78 -0
  158. package/test/core/DTComponentWithMeta.double.ts +115 -0
  159. package/test/core/DTComponentWithMeta.spec.ts +124 -0
  160. package/test/core/DTElement.double.ts +163 -0
  161. package/test/core/DTElement.spec.ts +146 -0
  162. package/test/core/DTError.double.ts +92 -0
  163. package/test/core/DTError.spec.ts +89 -0
  164. package/test/core/DTManager.double.ts +216 -0
  165. package/test/core/DTManager.spec.ts +965 -0
  166. package/test/core/DTMaster.double.ts +141 -0
  167. package/test/core/DTMaster.spec.ts +584 -0
  168. package/test/core/DTModule.double.ts +80 -0
  169. package/test/core/DTModule.spec.ts +138 -0
  170. package/test/core/copy.spec.ts +243 -0
  171. package/test/libs/DYOFinder.double.ts +152 -0
  172. package/test/libs/DYOFinder.spec.ts +194 -0
  173. package/test/libs/player/DTPlayer.element.double.ts +55 -0
  174. package/test/libs/player/DTPlayer.element.spec.ts +28 -0
  175. package/test/libs/player/DTPlayer.manager.double.ts +92 -0
  176. package/test/libs/player/DTPlayer.manager.spec.ts +178 -0
  177. package/tsconfig.dev.json +22 -0
  178. package/tsconfig.json +21 -0
  179. package/dist/core/DTPlayer.d.ts +0 -8
  180. package/dist/core/DTPlayer.js +0 -30
  181. package/dist/core/DTPlayer.js.map +0 -1
  182. package/dist/utils/filters.d.ts +0 -6
  183. package/dist/utils/filters.js +0 -39
  184. package/dist/utils/filters.js.map +0 -1
@@ -0,0 +1,897 @@
1
+ import { afterEach, beforeEach, describe, expect, jest, test, } from '@jest/globals';
2
+ import { defaultOptions, DTBunchStub, DTBunchTest, generateMockedElements, IDTest, KeyTest, } from './DTBunch.double';
3
+ import {
4
+ DTElementStub,
5
+ HaileiIdTest,
6
+ HaileiKeyTest,
7
+ HaileiToObjectTest,
8
+ IDTest as IDElementTest,
9
+ IldressIdTest,
10
+ IldressKeyTest,
11
+ IldressToObjectTest,
12
+ KeyTest as KeyElementTest,
13
+ MaydenaIdTest,
14
+ MaydenaKeyTest,
15
+ MaydenaToObjectTest,
16
+ MeldrineIdTest,
17
+ MeldrineKeyTest,
18
+ MeldrineToObjectTest,
19
+ YssaliaIdTest,
20
+ YssaliaKeyTest,
21
+ YssaliaToObjectTest,
22
+ } from './DTElement.double';
23
+ import { DTBunch, DTComponentPhysical } from '../../src';
24
+ import DYOToolsElement from '../../src/core/DTElement';
25
+ import { BunchMetaData, HaileiMetaData, IMetaDataTest } from './DTComponentWithMeta.double';
26
+ import { DTBunchOptions, FilterOperatorType } from '../../src/types';
27
+ import { checkCallForMockedDTError, CodeTest as DTErrorCodeTest, DTErrorStub } from './DTError.double';
28
+ import DYOToolsError from '../../src/core/DTError';
29
+ import { mockOverriddenMethods, OwnerTest } from './DTComponentPhysical.double';
30
+ import { DTManagerStub, IDTest as managerIDTest } from './DTManager.double';
31
+ import { componentBunchDefaultFinderConfiguration } from '../../src/constants';
32
+ import Mocked = jest.Mocked;
33
+ import MockedFunction = jest.MockedFunction;
34
+
35
+ /** ****************** MOCK DEPENDENCIES
36
+ * All Dependencies used by the component are mocked with Jest
37
+ * **** */
38
+ jest.mock('../../src/core/DTElement');
39
+ jest.mock('../../src/core/DTManager');
40
+ jest.mock('../../src/core/DTError');
41
+ jest.mock('../../src/core/DTComponent');
42
+ jest.mock('../../src/core/DTComponentWithMeta');
43
+ jest.mock('../../src/core/DTComponentPhysical');
44
+ jest.mock('../../src/libs/DYOFinder');
45
+ // Add specific mock for inherited methods to have a basic implementation
46
+ mockOverriddenMethods(DTComponentPhysical);
47
+
48
+ /** *********************** TESTS SUITES ****************************** */
49
+ describe('class DYOToolsBunch', () => {
50
+ let bunchTest: DTBunchTest;
51
+
52
+ beforeEach(() => {
53
+ bunchTest = new DTBunchTest();
54
+ bunchTest.th_set_options(defaultOptions);
55
+ });
56
+
57
+ afterEach(() => {
58
+ jest.resetAllMocks();
59
+ });
60
+
61
+ describe('inheritance', () => {
62
+ test('check good inheritance for class', () => {
63
+ expect(DTBunch.prototype instanceof DTComponentPhysical).toBeTruthy();
64
+ });
65
+ });
66
+
67
+ describe('constructor()', () => {
68
+ let addManyImpl;
69
+
70
+ beforeEach(() => {
71
+ jest.resetAllMocks();
72
+ addManyImpl = DTBunch.prototype.addMany;
73
+ DTBunch.prototype.addMany = jest.fn();
74
+ });
75
+
76
+ afterEach(() => {
77
+ DTBunch.prototype.addMany = addManyImpl;
78
+ });
79
+
80
+ test('creation simple with key', () => {
81
+ const newBunch = new DTBunchTest(KeyTest);
82
+ const parentConstructorMock = (DTComponentPhysical.prototype.constructor as MockedFunction<(key: string, options: any) => void>).mock;
83
+
84
+ expect(parentConstructorMock.calls[0][0]).toBe(KeyTest);
85
+ expect(parentConstructorMock.calls[0][1]).toStrictEqual(defaultOptions);
86
+ expect(newBunch.th_get_items()).toStrictEqual([]);
87
+
88
+ // Finder initialization
89
+ expect((newBunch.th_get_finder() as any).constructor.mock.calls.length).toBe(1);
90
+ expect((newBunch.th_get_finder() as any).constructor.mock.calls[0][0]).toStrictEqual(newBunch);
91
+ expect((newBunch.th_get_finder() as any).constructor.mock.calls[0][1]).toStrictEqual(componentBunchDefaultFinderConfiguration);
92
+ });
93
+
94
+ test('creation with items', () => {
95
+ new DTBunchTest(KeyTest, generateMockedElements(3));
96
+ const mockedAddMany = DTBunch.prototype.addMany as MockedFunction<(items: Array<Mocked<DYOToolsElement<IMetaDataTest>>>) => void>;
97
+
98
+ expect(mockedAddMany.mock.calls.length).toBe(1);
99
+ expect(mockedAddMany.mock.calls[0][0].length).toBe(3);
100
+ expect(mockedAddMany.mock.calls[0][0][0].getKey()).toBe(HaileiKeyTest);
101
+ expect(mockedAddMany.mock.calls[0][0][1].getKey()).toBe(MeldrineKeyTest);
102
+ expect(mockedAddMany.mock.calls[0][0][2].getKey()).toBe(MaydenaKeyTest);
103
+ });
104
+
105
+ test('creations with options', () => {
106
+ const testOptions: Partial<DTBunchOptions> = {
107
+ errors: true,
108
+ uniqueKey: true,
109
+ inheritOwner: true,
110
+ };
111
+ const newBunch = new DTBunchTest(KeyTest, [], testOptions);
112
+ const parentConstructorMock = (DTComponentPhysical.prototype.constructor as MockedFunction<(key: string, options: any) => void>).mock;
113
+
114
+ expect(parentConstructorMock.calls[0][0]).toBe(KeyTest);
115
+ expect(parentConstructorMock.calls[0][1]).toStrictEqual({
116
+ errors: true,
117
+ uniqueKey: true,
118
+ inheritOwner: true,
119
+ replaceIndex: false,
120
+ virtualContainer: false,
121
+ });
122
+ expect(newBunch.th_get_items()).toStrictEqual([]);
123
+ });
124
+ });
125
+
126
+ describe('_componentType', () => {
127
+ test('componentType must be "bunch"', () => {
128
+ expect(bunchTest.th_get_componentType()).toBe('bunch');
129
+ });
130
+ });
131
+
132
+ describe('getFinderConfiguration()', () => {
133
+ const baseOperators = [
134
+ FilterOperatorType.EQ,
135
+ FilterOperatorType.IN,
136
+ FilterOperatorType.NIN,
137
+ FilterOperatorType.NE,
138
+ ];
139
+ const advancedOperators = [
140
+ ...baseOperators,
141
+ FilterOperatorType.GTE,
142
+ FilterOperatorType.LTE,
143
+ FilterOperatorType.CONTAINS,
144
+ FilterOperatorType.NCONTAINS,
145
+ ];
146
+
147
+ test('check finder configuration for id attribute', () => {
148
+ const finderConfigurationToCheck = bunchTest.getFinderConfiguration().id;
149
+
150
+ expect(finderConfigurationToCheck.operators).toStrictEqual(baseOperators);
151
+ expect(finderConfigurationToCheck.getValue(new DTElementStub())).toBe(IDElementTest);
152
+ expect(finderConfigurationToCheck.objectSearch).toBe(false);
153
+ });
154
+
155
+ test('check finder configuration for key attribute', () => {
156
+ const finderConfigurationToCheck = bunchTest.getFinderConfiguration().key;
157
+
158
+ expect(finderConfigurationToCheck.operators).toStrictEqual(baseOperators);
159
+ expect(finderConfigurationToCheck.getValue(new DTElementStub())).toBe(KeyElementTest);
160
+ expect(finderConfigurationToCheck.objectSearch).toBe(false);
161
+ });
162
+
163
+ test('check finder configuration for owner attribute - empty owner', () => {
164
+ const element = new DTElementStub();
165
+ jest.spyOn(element, 'getOwner').mockImplementation(() => undefined);
166
+
167
+ const finderConfigurationToCheck = bunchTest.getFinderConfiguration().owner;
168
+
169
+ expect(finderConfigurationToCheck.operators).toStrictEqual(baseOperators);
170
+ expect(finderConfigurationToCheck.getValue(element)).toBeUndefined();
171
+ expect(finderConfigurationToCheck.objectSearch).toBe(false);
172
+ });
173
+
174
+ test('check finder configuration for owner attribute - with owner', () => {
175
+ const element = new DTElementStub();
176
+ jest.spyOn(element, 'getOwner').mockReturnValue(OwnerTest);
177
+
178
+ const finderConfigurationToCheck = bunchTest.getFinderConfiguration().owner;
179
+
180
+ expect(finderConfigurationToCheck.operators).toStrictEqual(baseOperators);
181
+ expect(finderConfigurationToCheck.getValue(element)).toBe(OwnerTest);
182
+ expect(finderConfigurationToCheck.objectSearch).toBe(false);
183
+ });
184
+
185
+ test('check finder configuration for container attribute - empty container', () => {
186
+ const element = new DTElementStub();
187
+ jest.spyOn(element, 'getContainer').mockImplementation(() => undefined);
188
+
189
+ const finderConfigurationToCheck = bunchTest.getFinderConfiguration().container;
190
+
191
+ expect(finderConfigurationToCheck.operators).toStrictEqual(baseOperators);
192
+ expect(finderConfigurationToCheck.getValue(element)).toBeNull();
193
+ expect(finderConfigurationToCheck.objectSearch).toBe(false);
194
+ });
195
+
196
+ test('check finder configuration for container attribute - with container', () => {
197
+ const element = new DTElementStub();
198
+ const bunch = new DTBunchStub();
199
+ jest.spyOn(bunch, 'getId').mockImplementation(() => `${IDTest}_other_container`);
200
+ jest.spyOn(element, 'getContainer').mockImplementation(() => bunch);
201
+
202
+ const finderConfigurationToCheck = bunchTest.getFinderConfiguration().container;
203
+
204
+ expect(finderConfigurationToCheck.operators).toStrictEqual(baseOperators);
205
+ expect(finderConfigurationToCheck.getValue(element)).toBe(`${IDTest}_other_container`);
206
+ expect(finderConfigurationToCheck.objectSearch).toBe(false);
207
+ });
208
+
209
+ test('check finder configuration for meta attribute', () => {
210
+ const element = new DTElementStub();
211
+ jest.spyOn(element, 'getManyMeta').mockImplementation(() => HaileiMetaData);
212
+
213
+ const finderConfigurationToCheck = bunchTest.getFinderConfiguration().meta;
214
+
215
+ expect(finderConfigurationToCheck.operators).toStrictEqual(advancedOperators);
216
+ expect(finderConfigurationToCheck.getValue(element)).toStrictEqual(HaileiMetaData);
217
+ expect(finderConfigurationToCheck.objectSearch).toBe(true);
218
+ });
219
+ });
220
+
221
+ describe('setOwner()', () => {
222
+ beforeEach(() => {
223
+ jest.spyOn(bunchTest, 'getOwner').mockReturnValue(OwnerTest);
224
+ });
225
+
226
+ test('add a new owner - not updating elements owner when inheritOwner = false', () => {
227
+ bunchTest.th_set_options({ inheritOwner: false });
228
+ bunchTest.th_set_items(generateMockedElements(3));
229
+
230
+ bunchTest.setOwner(OwnerTest);
231
+
232
+ expect(bunchTest.th_get_items()[0].setOwner.mock.calls.length).toBe(0);
233
+ expect(bunchTest.th_get_items()[1].setOwner.mock.calls.length).toBe(0);
234
+ expect(bunchTest.th_get_items()[2].setOwner.mock.calls.length).toBe(0);
235
+ });
236
+
237
+ test('add a new owner - updating elements owner when inheritOwner = true', () => {
238
+ bunchTest.th_set_options({ inheritOwner: true });
239
+ bunchTest.th_set_items(generateMockedElements(3));
240
+
241
+ bunchTest.setOwner(OwnerTest);
242
+
243
+ expect(bunchTest.th_get_items()[0].setOwner.mock.calls.length).toBe(1);
244
+ expect(bunchTest.th_get_items()[0].setOwner.mock.calls[0][0]).toBe(OwnerTest);
245
+ expect(bunchTest.th_get_items()[1].setOwner.mock.calls.length).toBe(1);
246
+ expect(bunchTest.th_get_items()[1].setOwner.mock.calls[0][0]).toBe(OwnerTest);
247
+ expect(bunchTest.th_get_items()[2].setOwner.mock.calls.length).toBe(1);
248
+ expect(bunchTest.th_get_items()[2].setOwner.mock.calls[0][0]).toBe(OwnerTest);
249
+ });
250
+ });
251
+
252
+ describe('removeOwner()', () => {
253
+ test('remove current Owner - not updating elements owner when inheritOwner = false', () => {
254
+ bunchTest.th_set_options({ inheritOwner: true });
255
+ bunchTest.th_set_items(generateMockedElements(2));
256
+
257
+ bunchTest.th_set_options({ inheritOwner: false });
258
+ bunchTest.removeOwner();
259
+
260
+ expect(bunchTest.th_get_items()[0].removeOwner.mock.calls.length).toBe(0);
261
+ expect(bunchTest.th_get_items()[1].removeOwner.mock.calls.length).toBe(0);
262
+ });
263
+
264
+ test('remove current Owner - updating elements owner when inheritOwner = true', () => {
265
+ bunchTest.th_set_options({ inheritOwner: true });
266
+ bunchTest.th_set_items(generateMockedElements(2));
267
+
268
+ bunchTest.removeOwner();
269
+
270
+ expect(bunchTest.th_get_items()[0].removeOwner.mock.calls.length).toBe(1);
271
+ expect(bunchTest.th_get_items()[1].removeOwner.mock.calls.length).toBe(1);
272
+ });
273
+ });
274
+
275
+ describe('get()', () => {
276
+ beforeEach(() => {
277
+ bunchTest.th_set_items(generateMockedElements(5));
278
+ });
279
+
280
+ test('return an item by its id', () => {
281
+ expect(bunchTest.get(`${MaydenaIdTest}-2`).getKey()).toBe(MaydenaKeyTest);
282
+ expect(bunchTest.get(`${YssaliaIdTest}-4`).getKey()).toBe(YssaliaKeyTest);
283
+ });
284
+
285
+ test('return an item by its index', () => {
286
+ expect(bunchTest.get(2).getKey()).toBe(MaydenaKeyTest);
287
+ expect(bunchTest.get(4).getKey()).toBe(YssaliaKeyTest);
288
+ });
289
+
290
+ test('return undefined if item not found by id', () => {
291
+ expect(bunchTest.get('id-123456')).toBeUndefined();
292
+ });
293
+
294
+ test('return undefined if item not found by index', () => {
295
+ expect(bunchTest.get(11)).toBeUndefined();
296
+ });
297
+
298
+ test('return undefined if item not found by index - incoherent index', () => {
299
+ expect(bunchTest.get(-11)).toBeUndefined();
300
+ });
301
+ });
302
+
303
+ describe('getAll()', () => {
304
+ test('return empty array if no items', () => {
305
+ expect(bunchTest.getAll()).toStrictEqual([]);
306
+ });
307
+
308
+ test('return all items array', () => {
309
+ bunchTest.th_set_items(generateMockedElements(5));
310
+
311
+ expect(bunchTest.getAll()[0].getKey()).toBe(HaileiKeyTest);
312
+ expect(bunchTest.getAll()[1].getKey()).toBe(MeldrineKeyTest);
313
+ expect(bunchTest.getAll()[2].getKey()).toBe(MaydenaKeyTest);
314
+ expect(bunchTest.getAll()[3].getKey()).toBe(IldressKeyTest);
315
+ expect(bunchTest.getAll()[4].getKey()).toBe(YssaliaKeyTest);
316
+ });
317
+ });
318
+
319
+ describe('indexOf()', () => {
320
+ beforeEach(() => {
321
+ bunchTest.th_set_items(generateMockedElements(5));
322
+ });
323
+
324
+ test('return index of an item by id', () => {
325
+ expect(bunchTest.indexOf(`${MaydenaIdTest}-2`)).toBe(2);
326
+ expect(bunchTest.indexOf(`${YssaliaIdTest}-4`)).toBe(4);
327
+ });
328
+
329
+ test('return -1 if id is not found', () => {
330
+ expect(bunchTest.indexOf('id-123456')).toBe(-1);
331
+ });
332
+ });
333
+
334
+ describe('addAtIndex()', () => {
335
+ let objectToAdd;
336
+ let objectsToAdd;
337
+
338
+ beforeEach(() => {
339
+ jest.spyOn(bunchTest, 'getId').mockReturnValue(IDTest);
340
+
341
+ bunchTest.th_set_items(generateMockedElements(5));
342
+
343
+ objectsToAdd = generateMockedElements(6);
344
+ objectToAdd = objectsToAdd[5];
345
+ jest.spyOn(bunchTest, 'find').mockReturnValue([objectToAdd]);
346
+ });
347
+
348
+ test('add a new item at last index - simple case', () => {
349
+ bunchTest.addAtIndex(objectToAdd, 5);
350
+
351
+ expect(bunchTest.th_get_items()[5].getId()).toBe(objectToAdd.getId());
352
+ });
353
+
354
+ test('add a new item at specified index and reindex - default case', () => {
355
+ bunchTest.addAtIndex(objectToAdd, 2);
356
+
357
+ expect(bunchTest.th_get_items()[2].getId()).toBe(objectToAdd.getId());
358
+ expect(bunchTest.th_get_items()[3].getId()).toBe(`${MaydenaIdTest}-2`);
359
+ expect(bunchTest.th_get_items()[4].getId()).toBe(`${IldressIdTest}-3`);
360
+ expect(bunchTest.th_get_items()[5].getId()).toBe(`${YssaliaIdTest}-4`);
361
+ });
362
+
363
+ test('add a new item at specified index and replace - replace option', () => {
364
+ bunchTest.addAtIndex(objectToAdd, 2, { replaceIndex: true });
365
+
366
+ expect(bunchTest.th_get_items()[2].getId()).toBe(objectToAdd.getId());
367
+ expect(bunchTest.th_get_items()[3].getId()).toBe(`${IldressIdTest}-3`);
368
+ expect(bunchTest.th_get_items()[4].getId()).toBe(`${YssaliaIdTest}-4`);
369
+ expect(bunchTest.th_get_items()[5]).toBeUndefined();
370
+ });
371
+
372
+ test('add a new item at lower index', () => {
373
+ bunchTest.addAtIndex(objectToAdd, -11);
374
+
375
+ expect(bunchTest.th_get_items()[0].getId()).toBe(objectToAdd.getId());
376
+ expect(bunchTest.th_get_items()[1].getId()).toBe(`${HaileiIdTest}-0`);
377
+ });
378
+
379
+ test('add a new item at greater index', () => {
380
+ bunchTest.addAtIndex(objectToAdd, 11);
381
+
382
+ expect(bunchTest.th_get_items()[5].getId()).toBe(objectToAdd.getId());
383
+ expect(bunchTest.th_get_items()[6]).toBeUndefined();
384
+ });
385
+
386
+ test('trigger conflict when adding two same ids - parent triggerError', () => {
387
+ const mockedTriggerError = DTBunch.prototype.triggerError as MockedFunction<(error: DYOToolsError) => void>;
388
+
389
+ bunchTest.addAtIndex(objectsToAdd[0], 2);
390
+
391
+ expect(mockedTriggerError.mock.calls.length).toBe(1);
392
+ checkCallForMockedDTError(
393
+ 'id_conflict',
394
+ 'Element with same id already exists in the bunch',
395
+ IDTest,
396
+ objectsToAdd[0].getId(),
397
+ );
398
+ });
399
+
400
+ test('no conflict when adding two same keys - default case', () => {
401
+ const mockedTriggerError = DTBunch.prototype.triggerError as MockedFunction<(error: DYOToolsError) => void>;
402
+
403
+ bunchTest.addAtIndex(objectToAdd, 2);
404
+
405
+ expect(mockedTriggerError.mock.calls.length).toBe(0);
406
+ expect((bunchTest.find as any).mock.calls.length).toBe(0);
407
+ expect(bunchTest.th_get_items()[0].getKey()).toBe(HaileiKeyTest);
408
+ expect(bunchTest.th_get_items()[2].getKey()).toBe(HaileiKeyTest);
409
+ });
410
+
411
+ test('trigger conflict when adding two same keys - uniqueKey option and parent triggerError', () => {
412
+ const mockedTriggerError = DTBunch.prototype.triggerError as MockedFunction<(error: DYOToolsError) => void>;
413
+
414
+ bunchTest.addAtIndex(objectToAdd, 2, { uniqueKey: true });
415
+
416
+ expect(mockedTriggerError.mock.calls.length).toBe(1);
417
+ checkCallForMockedDTError(
418
+ 'key_conflict',
419
+ 'Element with same key already exists in the bunch',
420
+ IDTest,
421
+ objectToAdd.getId(),
422
+ );
423
+ expect((bunchTest.find as any).mock.calls.length).toBe(1);
424
+ expect((bunchTest.find as any).mock.calls[0][0]).toStrictEqual({ key: { $eq: objectToAdd.getKey() } });
425
+ expect(bunchTest.th_get_items()[2].getId()).toBe(`${MaydenaIdTest}-2`);
426
+ });
427
+
428
+ test('not inherit owner when adding an item - default case', () => {
429
+ bunchTest.th_set_owner(OwnerTest);
430
+
431
+ bunchTest.addAtIndex(objectToAdd, 2);
432
+
433
+ expect(bunchTest.th_get_owner()).toBe(OwnerTest);
434
+ expect(objectToAdd.setOwner.mock.calls.length).toBe(0);
435
+ });
436
+
437
+ test('inherit owner when adding an item - inheritOwner option', () => {
438
+ bunchTest.th_set_owner(OwnerTest);
439
+
440
+ bunchTest.addAtIndex(objectToAdd, 2, { inheritOwner: true });
441
+
442
+ expect(bunchTest.th_get_owner()).toBe(OwnerTest);
443
+ expect(objectToAdd.setOwner.mock.calls.length).toBe(1);
444
+ expect(objectToAdd.setOwner.mock.calls[0][0]).toBe(OwnerTest);
445
+ });
446
+
447
+ test('not set context if undefined when adding an item', () => {
448
+ bunchTest.addAtIndex(objectToAdd, 2);
449
+
450
+ expect(bunchTest.th_get_items()[2].setContext.mock.calls.length).toBe(0);
451
+ });
452
+
453
+ test('set context with parent manager when adding an item', () => {
454
+ const manager = new DTManagerStub();
455
+ bunchTest.th_set_context(manager);
456
+
457
+ bunchTest.addAtIndex(objectToAdd, 2);
458
+
459
+ expect(bunchTest.th_get_items()[2].setContext.mock.calls.length).toBe(1);
460
+ expect(bunchTest.th_get_items()[2].setContext.mock.calls[0][0].getId()).toBe(managerIDTest);
461
+ });
462
+
463
+ test('set container when adding an item', () => {
464
+ bunchTest.addAtIndex(objectToAdd, 2);
465
+
466
+ expect(bunchTest.th_get_items()[2].setContainer.mock.calls.length).toBe(1);
467
+ expect(bunchTest.th_get_items()[2].setContainer.mock.calls[0][0].getId()).toBe(IDTest);
468
+ });
469
+
470
+ test('not set container when adding an item - virtualContainer option', () => {
471
+ bunchTest.th_set_options({ virtualContainer: true });
472
+
473
+ bunchTest.addAtIndex(objectToAdd, 2);
474
+
475
+ expect(bunchTest.th_get_items()[2].setContainer.mock.calls.length).toBe(0);
476
+ });
477
+
478
+ test('set container when adding an item - remove from old bunch', () => {
479
+ const bunchTestOld = new DTBunchTest();
480
+ bunchTestOld.th_set_items(generateMockedElements(6));
481
+ objectToAdd = bunchTestOld.th_get_items()[5];
482
+ objectToAdd.setContainer(bunchTestOld);
483
+ objectToAdd.setContainer.mockClear();
484
+ jest.spyOn(bunchTestOld, 'remove').mockImplementation(() => {});
485
+ jest.spyOn(bunchTestOld, 'getComponentType').mockImplementation(() => 'bunch');
486
+
487
+ bunchTest.addAtIndex(objectToAdd, 2);
488
+
489
+ expect(bunchTest.th_get_items()[2].setContainer.mock.calls.length).toBe(1);
490
+ expect(bunchTest.th_get_items()[2].setContainer.mock.calls[0][0].getId()).toBe(IDTest);
491
+ expect((bunchTestOld.remove as any).mock.calls.length).toBe(1);
492
+ expect((bunchTestOld.remove as any).mock.calls[0][0]).toBe(objectToAdd.getId());
493
+ });
494
+
495
+ test('set container when adding an item - dont remove if virtualContainer option', () => {
496
+ const bunchTestOld = new DTBunchTest();
497
+ bunchTestOld.th_set_items(generateMockedElements(6));
498
+ objectToAdd = bunchTestOld.th_get_items()[5];
499
+ jest.spyOn(bunchTestOld, 'remove').mockImplementation(() => {});
500
+
501
+ bunchTest.th_set_options({ virtualContainer: true });
502
+ bunchTest.addAtIndex(objectToAdd, 2);
503
+
504
+ expect(bunchTest.th_get_items()[2].setContainer.mock.calls.length).toBe(0);
505
+ expect((bunchTestOld.remove as any).mock.calls.length).toBe(0);
506
+ });
507
+
508
+ test('manager context - add item into the manager library', () => {
509
+ const managerTest = new DTManagerStub();
510
+ jest.spyOn(bunchTest, 'getContext').mockImplementation(
511
+ (contextType) => contextType === 'manager' && managerTest,
512
+ );
513
+ jest.spyOn(managerTest, 'getLibrary').mockImplementation(() => managerTest.th_get_library());
514
+ jest.spyOn(managerTest.th_get_library(), 'add');
515
+
516
+ bunchTest.addAtIndex(objectToAdd, 5);
517
+
518
+ expect((managerTest.th_get_library().add as any).mock.calls.length).toBe(1);
519
+ expect((managerTest.th_get_library().add as any).mock.calls[0][0]).toStrictEqual(objectToAdd);
520
+ });
521
+
522
+ test('manager context - not add existing item into the manager library', () => {
523
+ const managerTest = new DTManagerStub();
524
+ jest.spyOn(bunchTest, 'getContext').mockImplementation(
525
+ (contextType) => contextType === 'manager' && managerTest,
526
+ );
527
+ jest.spyOn(managerTest, 'getLibrary').mockImplementation(() => managerTest.th_get_library());
528
+ jest.spyOn(managerTest.th_get_library(), 'add');
529
+ managerTest.th_get_library().th_set_items([objectToAdd]);
530
+
531
+ bunchTest.addAtIndex(objectToAdd, 5);
532
+
533
+ expect((managerTest.th_get_library().add as any).mock.calls.length).toBe(0);
534
+ });
535
+ });
536
+
537
+ describe('add()', () => {
538
+ let objectsToAdd;
539
+ let objectToAdd;
540
+
541
+ beforeEach(() => {
542
+ jest.spyOn(bunchTest, 'addAtIndex').mockImplementation(() => {});
543
+
544
+ bunchTest.th_set_items(generateMockedElements(5));
545
+
546
+ objectsToAdd = generateMockedElements(6);
547
+ objectToAdd = objectsToAdd[5];
548
+ });
549
+
550
+ test('add as last item using addAtIndex', () => {
551
+ const testBunchOptions = {
552
+ replaceIndex: true,
553
+ inheritOwner: true,
554
+ };
555
+ bunchTest.add(objectToAdd, testBunchOptions);
556
+
557
+ expect((bunchTest.addAtIndex as any).mock.calls.length).toBe(1);
558
+ expect((bunchTest.addAtIndex as any).mock.calls[0][0].getId()).toBe(objectToAdd.getId());
559
+ expect((bunchTest.addAtIndex as any).mock.calls[0][1]).toBe(5);
560
+ expect((bunchTest.addAtIndex as any).mock.calls[0][2]).toStrictEqual(testBunchOptions);
561
+ });
562
+ });
563
+
564
+ describe('addManyAtIndex()', () => {
565
+ let itemsToAdd;
566
+ let itemLibrary;
567
+
568
+ beforeEach(() => {
569
+ jest.spyOn(bunchTest, 'addAtIndex').mockImplementation(() => {});
570
+
571
+ bunchTest.th_set_items(generateMockedElements(5));
572
+
573
+ itemLibrary = generateMockedElements(8);
574
+ itemsToAdd = [itemLibrary[5], itemLibrary[6], itemLibrary[7]];
575
+ });
576
+
577
+ test('add many items at index using addAtIndex - simple case', () => {
578
+ const testBunchOptions = {
579
+ replaceIndex: true,
580
+ inheritOwner: true,
581
+ };
582
+ const indexToAdd = 2;
583
+ bunchTest.addManyAtIndex(itemsToAdd, indexToAdd, testBunchOptions);
584
+
585
+ expect((bunchTest.addAtIndex as any).mock.calls.length).toBe(3);
586
+ for (let i = 0; i < 3; i++) {
587
+ expect((bunchTest.addAtIndex as any).mock.calls[i][0].getId()).toBe(itemsToAdd[i].getId());
588
+ expect((bunchTest.addAtIndex as any).mock.calls[i][1]).toBe(i + indexToAdd);
589
+ expect((bunchTest.addAtIndex as any).mock.calls[i][2]).toStrictEqual(testBunchOptions);
590
+ }
591
+ });
592
+
593
+ test('add many items at index using addAtIndex - index lower than 0', () => {
594
+ const indexToAdd = -11;
595
+ bunchTest.addManyAtIndex(itemsToAdd, indexToAdd);
596
+
597
+ expect((bunchTest.addAtIndex as any).mock.calls.length).toBe(3);
598
+ for (let i = 0; i < 3; i++) {
599
+ expect((bunchTest.addAtIndex as any).mock.calls[i][0].getId()).toBe(itemsToAdd[i].getId());
600
+ expect((bunchTest.addAtIndex as any).mock.calls[i][1]).toBe(i);
601
+ }
602
+ });
603
+
604
+ test('errors when adding many items at index - default case - add no items and throw error', () => {
605
+ const indexToAdd = 2;
606
+ let errorThrown: DTErrorStub;
607
+ jest.spyOn(bunchTest, 'addAtIndex').mockImplementationOnce((item, index, options) => {
608
+ throw new DTErrorStub();
609
+ });
610
+
611
+ try {
612
+ bunchTest.addManyAtIndex(itemsToAdd, indexToAdd);
613
+ } catch (error: unknown) {
614
+ errorThrown = error as DTErrorStub;
615
+ }
616
+
617
+ expect(errorThrown).toBeDefined();
618
+ expect(DTErrorStub).toHaveBeenCalled();
619
+ expect(errorThrown.getCode()).toBe(DTErrorCodeTest);
620
+ expect((bunchTest.addAtIndex as any).mock.calls.length).toBe(1);
621
+ expect((bunchTest.addAtIndex as any).mock.calls[0][0].getId()).toBe(itemsToAdd[0].getId());
622
+ expect((bunchTest.addAtIndex as any).mock.calls[0][1]).toBe(indexToAdd);
623
+ });
624
+
625
+ test('errors when adding many items at index - errors case - add success items and stack errors for others', () => {
626
+ const indexToAdd = 2;
627
+ const errors = [];
628
+ jest.spyOn(bunchTest, 'addAtIndex')
629
+ .mockImplementationOnce((item, index, options) => {
630
+ errors.push(new DTErrorStub());
631
+ })
632
+ .mockImplementationOnce((item, index, options) => {
633
+ errors.push(new DTErrorStub());
634
+ });
635
+
636
+ bunchTest.addManyAtIndex(itemsToAdd, indexToAdd, { errors: true });
637
+
638
+ expect(errors.length).toBe(2);
639
+ expect(DTErrorStub).toHaveBeenCalled();
640
+ expect((bunchTest.addAtIndex as any).mock.calls.length).toBe(3);
641
+ expect((bunchTest.addAtIndex as any).mock.calls[0][0].getId()).toBe(itemsToAdd[0].getId());
642
+ expect((bunchTest.addAtIndex as any).mock.calls[1][0].getId()).toBe(itemsToAdd[1].getId());
643
+ expect((bunchTest.addAtIndex as any).mock.calls[2][0].getId()).toBe(itemsToAdd[2].getId());
644
+ });
645
+ });
646
+
647
+ describe('addMany()', () => {
648
+ let itemsToAdd;
649
+ let itemLibrary;
650
+
651
+ beforeEach(() => {
652
+ jest.spyOn(bunchTest, 'addManyAtIndex').mockImplementation(() => {});
653
+
654
+ bunchTest.th_set_items(generateMockedElements(5));
655
+
656
+ itemLibrary = generateMockedElements(8);
657
+ itemsToAdd = [itemLibrary[5], itemLibrary[6], itemLibrary[7]];
658
+ });
659
+
660
+ test('add many items as last item using addManyAtIndex', () => {
661
+ const testBunchOptions = {
662
+ replaceIndex: true,
663
+ inheritOwner: true,
664
+ };
665
+
666
+ bunchTest.addMany(itemsToAdd, testBunchOptions);
667
+
668
+ expect((bunchTest.addManyAtIndex as any).mock.calls.length).toBe(1);
669
+ expect((bunchTest.addManyAtIndex as any).mock.calls[0][0].length).toBe(3);
670
+ expect((bunchTest.addManyAtIndex as any).mock.calls[0][0][0].getId()).toBe(`${HaileiIdTest}-5`);
671
+ expect((bunchTest.addManyAtIndex as any).mock.calls[0][0][1].getId()).toBe(`${MeldrineIdTest}-6`);
672
+ expect((bunchTest.addManyAtIndex as any).mock.calls[0][0][2].getId()).toBe(`${MaydenaIdTest}-7`);
673
+ expect((bunchTest.addManyAtIndex as any).mock.calls[0][1]).toBe(5);
674
+ expect((bunchTest.addManyAtIndex as any).mock.calls[0][2]).toStrictEqual(testBunchOptions);
675
+ });
676
+ });
677
+
678
+ describe('removeMany()', () => {
679
+ const checkAllItemsInBunch = (bunch: DTBunchTest, itemRemoved = 3) => {
680
+ const sup = itemRemoved;
681
+ expect(bunchTest.getAll().length).toBe(5 - sup);
682
+ expect(bunchTest.th_get_items()[0].getId()).toBe(`${HaileiIdTest}-0`);
683
+ itemRemoved < 1 && expect(bunchTest.th_get_items()[1 - sup].getId()).toBe(`${MeldrineIdTest}-1`);
684
+ itemRemoved < 2 && expect(bunchTest.th_get_items()[2 - sup].getId()).toBe(`${MaydenaIdTest}-2`);
685
+ itemRemoved < 3 && expect(bunchTest.th_get_items()[3 - sup].getId()).toBe(`${IldressIdTest}-3`);
686
+ expect(bunchTest.th_get_items()[4 - sup].getId()).toBe(`${YssaliaIdTest}-4`);
687
+ };
688
+
689
+ beforeEach(() => {
690
+ bunchTest.th_set_items(generateMockedElements(5));
691
+ });
692
+
693
+ test('remove many items by ids', () => {
694
+ bunchTest.removeMany([`${MeldrineIdTest}-1`, `${MaydenaIdTest}-2`, `${IldressIdTest}-3`]);
695
+
696
+ checkAllItemsInBunch(bunchTest);
697
+ });
698
+
699
+ test('remove many items by indexes', () => {
700
+ bunchTest.removeMany([1, 2, 3]);
701
+
702
+ checkAllItemsInBunch(bunchTest);
703
+ });
704
+
705
+ test('remove only item with corresponding ids', () => {
706
+ bunchTest.removeMany([`${MeldrineIdTest}-1`, `${MaydenaIdTest}-2`, 'id-12345']);
707
+
708
+ checkAllItemsInBunch(bunchTest, 2);
709
+ });
710
+
711
+ test('remove only item with corresponding indexes', () => {
712
+ bunchTest.removeMany([1, 2, 11]);
713
+
714
+ checkAllItemsInBunch(bunchTest, 2);
715
+ });
716
+
717
+ test('remove only item with corresponding indexes - incoherent index', () => {
718
+ bunchTest.removeMany([-11, 2, 1, -13]);
719
+
720
+ checkAllItemsInBunch(bunchTest, 2);
721
+ });
722
+
723
+ test('define container at undefined for removed items - default case', () => {
724
+ const items = [
725
+ bunchTest.th_get_items()[1],
726
+ bunchTest.th_get_items()[2],
727
+ ];
728
+
729
+ bunchTest.removeMany([`${MeldrineIdTest}-1`, `${MaydenaIdTest}-2`]);
730
+ items.push(bunchTest.th_get_items()[0]);
731
+ items.push(bunchTest.th_get_items()[1]);
732
+ bunchTest.removeMany([0, 1]);
733
+
734
+ expect(items[0].removeContainer.mock.calls.length).toBe(1);
735
+ expect(items[1].removeContainer.mock.calls.length).toBe(1);
736
+ expect(items[2].removeContainer.mock.calls.length).toBe(1);
737
+ expect(items[3].removeContainer.mock.calls.length).toBe(1);
738
+ });
739
+
740
+ test('not change container for removed items - virtual container option', () => {
741
+ const items = [
742
+ bunchTest.th_get_items()[1],
743
+ bunchTest.th_get_items()[2],
744
+ ];
745
+ bunchTest.th_set_options({ virtualContainer: true });
746
+ bunchTest.removeMany([`${MeldrineIdTest}-1`, `${MaydenaIdTest}-2`]);
747
+ items.push(bunchTest.th_get_items()[0]);
748
+ items.push(bunchTest.th_get_items()[1]);
749
+ bunchTest.removeMany([0, 1]);
750
+
751
+ expect(items[0].removeContainer.mock.calls.length).toBe(0);
752
+ expect(items[1].removeContainer.mock.calls.length).toBe(0);
753
+ expect(items[2].removeContainer.mock.calls.length).toBe(0);
754
+ expect(items[3].removeContainer.mock.calls.length).toBe(0);
755
+ });
756
+ });
757
+
758
+ describe('remove()', () => {
759
+ beforeEach(() => {
760
+ jest.spyOn(bunchTest, 'removeMany').mockImplementation(() => {
761
+ });
762
+
763
+ bunchTest.th_set_items(generateMockedElements(5));
764
+ });
765
+
766
+ test('remove one item by id using removeMany', () => {
767
+ bunchTest.remove(`${MaydenaIdTest}-2`);
768
+
769
+ expect((bunchTest.removeMany as any).mock.calls.length).toBe(1);
770
+ expect((bunchTest.removeMany as any).mock.calls[0][0]).toStrictEqual([`${MaydenaIdTest}-2`]);
771
+ });
772
+
773
+ test('remove one item by index using removeMany', () => {
774
+ bunchTest.remove(2);
775
+
776
+ expect((bunchTest.removeMany as any).mock.calls.length).toBe(1);
777
+ expect((bunchTest.removeMany as any).mock.calls[0][0]).toStrictEqual([2]);
778
+ });
779
+ });
780
+
781
+ describe('removeAll()', () => {
782
+ beforeEach(() => {
783
+ jest.spyOn(bunchTest, 'removeMany').mockImplementation(() => {
784
+ });
785
+
786
+ bunchTest.th_set_items(generateMockedElements(5));
787
+ });
788
+
789
+ test('remove all items using removeMany', () => {
790
+ bunchTest.removeAll();
791
+
792
+ expect((bunchTest.removeMany as any).mock.calls.length).toBe(1);
793
+ expect((bunchTest.removeMany as any).mock.calls[0][0]).toStrictEqual([0, 1, 2, 3, 4]);
794
+ });
795
+ });
796
+
797
+ describe('copy()', () => {
798
+ // @see copy.spec.ts for unit tests about copy method
799
+ });
800
+
801
+ describe('find()', () => {
802
+ test('find items using DYOFinder - empty case', () => {
803
+ bunchTest.find({});
804
+
805
+ expect((bunchTest.th_get_finder() as any).execute.mock.calls.length).toBe(1);
806
+ expect((bunchTest.th_get_finder() as any).execute.mock.calls[0][0]).toStrictEqual({});
807
+ });
808
+
809
+ test('find items using DYOFinder', () => {
810
+ const testFilters = { id: { $eq: 'id_bunch' }, key: { $ne: 'key_test' } };
811
+ bunchTest.find(testFilters);
812
+
813
+ expect((bunchTest.th_get_finder() as any).execute.mock.calls.length).toBe(1);
814
+ expect((bunchTest.th_get_finder() as any).execute.mock.calls[0][0]).toStrictEqual(testFilters);
815
+ });
816
+ });
817
+
818
+ describe('toObject()', () => {
819
+ beforeEach(() => {
820
+ bunchTest.th_set_id(IDTest);
821
+ bunchTest.th_set_key(KeyTest);
822
+ });
823
+
824
+ test('toObject output standard', () => {
825
+ const toObjectBunch = bunchTest.toObject();
826
+
827
+ expect(Object.keys(toObjectBunch)).toStrictEqual(['id', 'key', 'type', 'items']);
828
+ expect(toObjectBunch.id).toBe(IDTest);
829
+ expect(toObjectBunch.key).toBe(KeyTest);
830
+ expect(toObjectBunch.type).toBe('bunch');
831
+ expect(toObjectBunch.items.length).toBe(0);
832
+ });
833
+
834
+ test('toObject output standard with owner', () => {
835
+ bunchTest.th_set_owner(OwnerTest);
836
+
837
+ const toObjectBunch = bunchTest.toObject();
838
+ expect(Object.keys(toObjectBunch)).toStrictEqual(['id', 'key', 'type', 'items', 'owner']);
839
+ expect(toObjectBunch.owner).toBe(OwnerTest);
840
+ });
841
+
842
+ test('toObject output standard with owner and meta', () => {
843
+ jest.spyOn(bunchTest, 'getManyMeta').mockImplementation(function () {
844
+ return this._meta;
845
+ });
846
+
847
+ bunchTest.th_set_owner(OwnerTest);
848
+ bunchTest.th_set_meta(BunchMetaData);
849
+
850
+ const toObjectBunch = bunchTest.toObject();
851
+ expect(Object.keys(toObjectBunch)).toStrictEqual(['id', 'key', 'type', 'items', 'owner', 'meta']);
852
+ expect(toObjectBunch.meta).toStrictEqual(BunchMetaData);
853
+ });
854
+
855
+ test('toObject output standard with items', () => {
856
+ bunchTest.th_set_items(generateMockedElements(5));
857
+ const toObjectBunch = bunchTest.toObject();
858
+
859
+ expect(Object.keys(toObjectBunch)).toStrictEqual(['id', 'key', 'type', 'items']);
860
+ expect(toObjectBunch.items.length).toBe(5);
861
+ expect(toObjectBunch.items).toStrictEqual([
862
+ HaileiToObjectTest,
863
+ MeldrineToObjectTest,
864
+ MaydenaToObjectTest,
865
+ IldressToObjectTest,
866
+ YssaliaToObjectTest,
867
+ ]);
868
+ });
869
+ });
870
+
871
+ describe('toString()', () => {
872
+ beforeEach(() => {
873
+ bunchTest.th_set_key(KeyTest);
874
+ });
875
+
876
+ test('string output standard', () => {
877
+ const toStringBunch = bunchTest.toString();
878
+
879
+ expect(toStringBunch).toBe(`Component ${KeyTest} - Type: Bunch - Items: 0`);
880
+ });
881
+
882
+ test('string output standard with items', () => {
883
+ bunchTest.th_set_items(generateMockedElements(5));
884
+ const toStringBunch = bunchTest.toString();
885
+
886
+ expect(toStringBunch).toBe(`Component ${KeyTest} - Type: Bunch - Items: 5`);
887
+ });
888
+
889
+ test('string output standard with items and owner', () => {
890
+ bunchTest.th_set_items(generateMockedElements(5));
891
+ bunchTest.th_set_owner(OwnerTest);
892
+
893
+ const toStringBunch = bunchTest.toString();
894
+ expect(toStringBunch).toBe(`Component ${KeyTest} - Type: Bunch - Owner: ${OwnerTest} - Items: 5`);
895
+ });
896
+ });
897
+ });