areconnectedthroughproperties.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /* globals window, document, Event */
  6. import areConnectedThroughProperties from '../src/areconnectedthroughproperties';
  7. describe( 'areConnectedThroughProperties()', () => {
  8. it( 'should return `false` if one of the value is primitive #1', () => {
  9. const el1 = [ 'foo' ];
  10. const el2 = 'foo';
  11. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  12. } );
  13. it( 'should return `false` if one of the value is primitive #2', () => {
  14. const el1 = 0;
  15. const el2 = [ 0 ];
  16. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  17. } );
  18. it( 'should return `false` if both of the values are primitives', () => {
  19. const el1 = null;
  20. const el2 = null;
  21. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  22. } );
  23. it( 'should return `false` if both values are plain objects', () => {
  24. const el1 = {};
  25. const el2 = {};
  26. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  27. } );
  28. it( 'should return `true` if both objects references to the same object', () => {
  29. const el1 = {};
  30. const el2 = el1;
  31. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.true;
  32. } );
  33. it( 'should return `true` if both values share a common reference #1', () => {
  34. const foo = {};
  35. const el1 = { foo };
  36. const el2 = { foo };
  37. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.true;
  38. } );
  39. it( 'should return `true` if both values share a common reference #2', () => {
  40. const foo = [];
  41. const el1 = [ foo ];
  42. const el2 = [ foo ];
  43. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.true;
  44. } );
  45. it( 'should return `true` if the first structure is deep inside the second structure', () => {
  46. const el1 = {};
  47. const el2 = {
  48. foo: 1,
  49. bar: [ 1, 2, 3, new Map( [
  50. [ {}, new Set( [ 1, 2, 3 ] ) ],
  51. [ undefined, new Set( [
  52. Symbol( 'foo' ),
  53. null,
  54. { x: [ el1 ] }
  55. ] ) ]
  56. ] ) ]
  57. };
  58. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.true;
  59. } );
  60. it( 'should return `true` if the second structure is deep inside the first structure', () => {
  61. const el2 = {};
  62. const el1 = {
  63. foo: 1,
  64. bar: [ 1, 2, 3, new Map( [
  65. [ {}, new Set( [ 1, 2, 3 ] ) ],
  66. [ undefined, new Set( [
  67. Symbol( 'foo' ),
  68. null,
  69. { x: [ el2 ] }
  70. ] ) ]
  71. ] ) ]
  72. };
  73. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.true;
  74. } );
  75. it( 'should return `true` if both structures have a common reference', () => {
  76. const foo = {};
  77. const el1 = {
  78. foo: 1,
  79. bar: [ 1, 2, 3, new Map( [
  80. [ {}, new Set( [ 1, 2, 3 ] ) ],
  81. [ undefined, new Set( [
  82. Symbol( 'foo' ),
  83. null,
  84. { x: [ foo ] }
  85. ] ) ]
  86. ] ) ]
  87. };
  88. const el2 = {
  89. foo: 1,
  90. bar: [ 1, 2, 3, new Map( [
  91. [ {}, new Set( [ 1, 2, 3 ] ) ],
  92. [ undefined, new Set( [
  93. Symbol( 'foo' ),
  94. null,
  95. { x: [ foo ] }
  96. ] ) ]
  97. ] ) ]
  98. };
  99. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.true;
  100. } );
  101. it( 'should return `false` if the structures is not connected #1', () => {
  102. const el1 = {};
  103. const el2 = {
  104. foo: 1,
  105. bar: [ 1, 2, 3, new Map( [
  106. [ {}, new Set( [ 1, 2, 3 ] ) ],
  107. [ undefined, new Set( [
  108. Symbol( 'foo' ),
  109. null,
  110. { x: [] }
  111. ] ) ]
  112. ] ) ]
  113. };
  114. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  115. } );
  116. it( 'should return `false` if the structures is not connected #2', () => {
  117. const el1 = {
  118. foo: 1,
  119. bar: [ 1, 2, 3, new Map( [
  120. [ {}, new Set( [ 1, 2, 3 ] ) ],
  121. [ undefined, new Set( [
  122. Symbol( 'foo' ),
  123. null,
  124. { x: [] }
  125. ] ) ]
  126. ] ) ]
  127. };
  128. const el2 = {
  129. foo: 1,
  130. bar: [ 1, 2, 3, new Map( [
  131. [ {}, new Set( [ 1, 2, 3 ] ) ],
  132. [ undefined, new Set( [
  133. Symbol( 'foo' ),
  134. null,
  135. { x: [] }
  136. ] ) ]
  137. ] ) ]
  138. };
  139. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  140. } );
  141. it( 'should work well with nested objects #1', () => {
  142. const el1 = {};
  143. el1.foo = el1;
  144. const el2 = {};
  145. el2.foo = el2;
  146. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  147. } );
  148. it( 'should work well with nested objects #2', () => {
  149. const el1 = {};
  150. el1.foo = el1;
  151. const el2 = {};
  152. el2.foo = {
  153. foo: el2,
  154. bar: el1
  155. };
  156. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.true;
  157. } );
  158. it( 'should skip DOM objects', () => {
  159. const evt = new Event( 'click' );
  160. const el1 = { window, document, evt };
  161. const el2 = { window, document, evt };
  162. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  163. } );
  164. it( 'should skip date and regexp objects', () => {
  165. const date = new Date();
  166. const regexp = /123/;
  167. const el1 = { date, regexp };
  168. const el2 = { date, regexp };
  169. expect( areConnectedThroughProperties( el1, el2 ) ).to.be.false;
  170. } );
  171. } );