Object.spec.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. import {
  2. isObjectEquals,
  3. duckSchema,
  4. mixin,
  5. clone,
  6. deepExtend,
  7. deepObjectSize,
  8. createObjectPropListener,
  9. } from 'handsontable/helpers/object';
  10. describe('Object helper', () => {
  11. //
  12. // Handsontable.helper.isObjectEquals
  13. //
  14. describe('isObjectEquals', () => {
  15. it('should returns true on equal objects', () => {
  16. expect(isObjectEquals({}, {})).toBe(true);
  17. expect(isObjectEquals({test: 1}, {test: 1})).toBe(true);
  18. expect(isObjectEquals({test: {test2: [{}]}}, {test: {test2: [{}]}})).toBe(true);
  19. expect(isObjectEquals([], [])).toBe(true);
  20. expect(isObjectEquals([33], [33])).toBe(true);
  21. expect(isObjectEquals([{test: 1}], [{test: 1}])).toBe(true);
  22. });
  23. it('should returns false for not equal objects', () => {
  24. expect(isObjectEquals({}, [])).toBe(false);
  25. expect(isObjectEquals({test: 2}, {test: 1})).toBe(false);
  26. expect(isObjectEquals({test: {test3: [{}]}}, {test: {test2: [{}]}})).toBe(false);
  27. expect(isObjectEquals([12], [33])).toBe(false);
  28. expect(isObjectEquals([{test: 3}], [{test: 1}])).toBe(false);
  29. });
  30. });
  31. //
  32. // Handsontable.helper.duckSchema
  33. //
  34. describe('duckSchema', () => {
  35. it('should returns valid schema object', () => {
  36. expect(duckSchema({})).toEqual({});
  37. expect(duckSchema({test: 1})).toEqual({test: null});
  38. expect(duckSchema({test: 'foo'})).toEqual({test: null});
  39. expect(duckSchema({test: undefined})).toEqual({test: null});
  40. expect(duckSchema({test: null})).toEqual({test: null});
  41. expect(duckSchema({test: []})).toEqual({test: []});
  42. expect(duckSchema({test: [1, 2, 3]})).toEqual({test: []});
  43. });
  44. it('should returns valid schema object (deeply)', () => {
  45. expect(duckSchema({test: {a: {b: 11}}})).toEqual({test: {a: {b: null}}});
  46. expect(duckSchema({test: {a: {b: []}}})).toEqual({test: {a: {b: []}}});
  47. expect(duckSchema({test: {a: {b: [{q: 1, w: 2}]}}})).toEqual({test: {a: {b: [{q: null, w: null}]}}});
  48. });
  49. });
  50. //
  51. // Handsontable.helper.mixin
  52. //
  53. describe('mixin', () => {
  54. it('should mix base object from one object', () => {
  55. var Base = function() {};
  56. var MixinFoo = {
  57. local: 'value',
  58. myFunction() {
  59. return this.local;
  60. },
  61. mySetterFunction(value) {
  62. this.local = value;
  63. }
  64. };
  65. mixin(Base, MixinFoo);
  66. var instance = new Base();
  67. expect(instance.myFunction()).toBe('value');
  68. expect(instance.local).toBe('value');
  69. instance.local = 123;
  70. expect(instance.myFunction()).toBe(123);
  71. expect(instance.local).toBe(123);
  72. var initialObject = {a: 1};
  73. instance.mySetterFunction(initialObject);
  74. expect(instance.myFunction()).toBe(initialObject);
  75. expect(instance.local).toBe(initialObject);
  76. });
  77. it('should mix base object from multiple objects', () => {
  78. var Base = function() {};
  79. var MixinFoo = {
  80. local: 'value',
  81. myFunction() {
  82. return this.local;
  83. },
  84. mySetterFunction(value) {
  85. this.local = value;
  86. }
  87. };
  88. var MixinBar = {
  89. test: {zzz: 2}
  90. };
  91. var MixinBaz = {
  92. getTest() {
  93. return this.test;
  94. }
  95. };
  96. mixin(Base, MixinFoo, MixinBar, MixinBaz);
  97. var instance = new Base();
  98. expect(instance.myFunction()).toBe('value');
  99. expect(instance.local).toBe('value');
  100. expect(instance.test).not.toBe(MixinBar.test);
  101. expect(instance.test).toEqual(MixinBar.test);
  102. expect(instance.test.zzz).toBe(2);
  103. expect(instance.getTest()).not.toBe(MixinBar.test);
  104. expect(instance.getTest()).toEqual(MixinBar.test);
  105. });
  106. it('mixed object should not interfere with properties from another mixed objects', () => {
  107. var Base = function() {};
  108. var Base1 = function() {};
  109. var MixinFoo = {
  110. local: {},
  111. myFunction() {
  112. this.local.test = 1;
  113. return this.local.test;
  114. }
  115. };
  116. mixin(Base, MixinFoo);
  117. mixin(Base1, MixinFoo);
  118. var instance = new Base();
  119. var instance1 = new Base1();
  120. instance.myFunction();
  121. expect(instance.local.test).toEqual(1);
  122. expect(instance1.local.test).not.toBeDefined();
  123. });
  124. });
  125. //
  126. // Handsontable.helper.clone
  127. //
  128. describe('clone', () => {
  129. it('should returns cloned object', () => {
  130. var function1 = function() {};
  131. var object1 = {};
  132. var object2 = {
  133. foo: false,
  134. und: void 0,
  135. bar: 0,
  136. baz: object1,
  137. func: function1,
  138. };
  139. expect(clone(object1)).toEqual({});
  140. expect(clone(object1)).not.toBe(object1);
  141. expect(clone(object2)).toEqual(object2);
  142. expect(clone(object2)).not.toBe(object2);
  143. expect(clone(object2).baz).toBe(object2.baz);
  144. expect(clone(object2).func).toBe(function1);
  145. });
  146. });
  147. //
  148. // Handsontable.helper.deepExtend
  149. //
  150. describe('deepExtend', () => {
  151. it('should extend an object with all the properties of another object (recursively)', () => {
  152. var baseObject = {
  153. test: 'one',
  154. anotherTest: ['one, two']
  155. };
  156. var date = new Date();
  157. var partial = {
  158. prop1: 'prop1',
  159. prop2: 34,
  160. prop3: [
  161. 12,
  162. 'test',
  163. {
  164. prop: 'one'
  165. },
  166. [0, 1]
  167. ],
  168. prop4: {
  169. p1: 0,
  170. p2: [0, 1],
  171. p3: {
  172. a: 'b'
  173. }
  174. },
  175. prop5: date
  176. };
  177. deepExtend(baseObject, partial);
  178. expect(baseObject.test).toEqual('one');
  179. expect(baseObject.anotherTest).toEqual(['one, two']);
  180. expect(baseObject.prop1).toEqual('prop1');
  181. expect(baseObject.prop2).toEqual(34);
  182. expect(baseObject.prop3[0]).toEqual(12);
  183. expect(baseObject.prop3[1]).toEqual('test');
  184. expect(baseObject.prop3[2].prop).toEqual('one');
  185. expect(baseObject.prop3[3]).toEqual([0, 1]);
  186. expect(baseObject.prop4.p1).toEqual(0);
  187. expect(baseObject.prop4.p2).toEqual([0, 1]);
  188. expect(baseObject.prop4.p3.a).toEqual('b');
  189. expect(baseObject.prop5).toEqual(date);
  190. });
  191. });
  192. //
  193. // Handsontable.helper.deepObjectSize
  194. //
  195. describe('deepObjectSize', () => {
  196. it('should return false if a variable is not an object', () => {
  197. var toCount = [
  198. 1,
  199. 2,
  200. 3
  201. ];
  202. expect(deepObjectSize(toCount)).toBeFalsy();
  203. });
  204. it('should return an object keys length (recursively and only these keys, which contain value)', () => {
  205. var toCount = {
  206. prop1: 1,
  207. prop2: 2,
  208. prop3: {
  209. prop31: {
  210. prop311: 311,
  211. prop312: 312
  212. },
  213. prop32: 32,
  214. prop33: 33
  215. },
  216. prop4: 4,
  217. prop5: 5
  218. };
  219. expect(deepObjectSize(toCount)).toEqual(8);
  220. });
  221. });
  222. //
  223. // Handsontable.helper.createObjectPropListener
  224. //
  225. describe('createObjectPropListener', () => {
  226. it('should returns object listener and listen default property', () => {
  227. var propListener = createObjectPropListener('foo');
  228. expect(propListener.isTouched()).toBe(false);
  229. expect(propListener.value).toBe('foo');
  230. propListener.test = 'bar';
  231. expect(propListener.isTouched()).toBe(false);
  232. expect(propListener.value).toBe('foo');
  233. propListener.value = 'bar';
  234. expect(propListener.isTouched()).toBe(true);
  235. expect(propListener.value).toBe('bar');
  236. expect(propListener.test).toBe('bar');
  237. });
  238. it('should returns object listener and listen defined by user property', () => {
  239. var propListener = createObjectPropListener('foo', 'me');
  240. expect(propListener.isTouched()).toBe(false);
  241. expect(propListener.me).toBe('foo');
  242. propListener.value = 'bar';
  243. expect(propListener.isTouched()).toBe(false);
  244. expect(propListener.me).toBe('foo');
  245. expect(propListener.value).toBe('bar');
  246. propListener.me = 'bar';
  247. expect(propListener.isTouched()).toBe(true);
  248. expect(propListener.value).toBe('bar');
  249. expect(propListener.me).toBe('bar');
  250. });
  251. it('should detect change value to undefined', () => {
  252. var propListener = createObjectPropListener('foo');
  253. propListener.value = void 0;
  254. expect(propListener.isTouched()).toBe(true);
  255. expect(propListener.value).toBe(void 0);
  256. });
  257. });
  258. });