utils.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. /**
  6. * General test utils for CKEditor.
  7. */
  8. const utils = {
  9. sinon,
  10. /**
  11. * Creates Sinon sandbox in {@link utils#sinon} and plugs `afterEach()` callback which
  12. * restores all spies and stubs created in this sandbox.
  13. *
  14. * See https://github.com/ckeditor/ckeditor5-design/issues/72 and http://sinonjs.org/docs/#sinon-sandbox
  15. *
  16. * Usage:
  17. *
  18. * import testUtils from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
  19. *
  20. * describe( 'MyClass', () => {
  21. * // Create Sinon sandbox inside top-level describe block:
  22. * testUtils.createSinonSandbox();
  23. *
  24. * // Then inside tests you can use testUtils.sinon:
  25. * it( 'does something', () => {
  26. * testUtils.sinon.spy( obj, 'method' );
  27. * } );
  28. * }
  29. *
  30. * **Note**: Do not use `testUtils.createSinonSandbox()` outside `describe()` block as it will attach `afterEach()` calls
  31. * to all test - not only those in current file.
  32. */
  33. createSinonSandbox() {
  34. // eslint-disable-next-line mocha/no-top-level-hooks
  35. afterEach( () => {
  36. utils.sinon.restore();
  37. } );
  38. },
  39. /**
  40. * Executes specified assertions. It expects that at least one function will not throw an error.
  41. *
  42. * Some of the tests fail because different browsers renders selection differently when it comes to element boundaries.
  43. * Using this method we can check few scenarios.
  44. *
  45. * See https://github.com/ckeditor/ckeditor5-core/issues/107.
  46. *
  47. * Usage:
  48. *
  49. * it( 'test', () => {
  50. * // Test bootstrapping...
  51. *
  52. * const assertEdge = () => {
  53. * // expect();
  54. * };
  55. *
  56. * const assertAll = () => {
  57. * // expect();
  58. * };
  59. *
  60. * testUtils.checkAssertions( assertEdge, assertAll );
  61. * } );
  62. *
  63. * @param {...Function} assertions Functions that will be executed.
  64. */
  65. checkAssertions( ...assertions ) {
  66. const errors = [];
  67. for ( const assertFn of assertions ) {
  68. try {
  69. assertFn();
  70. return;
  71. } catch ( err ) {
  72. errors.push( err.message );
  73. }
  74. }
  75. throw new Error( errors.join( '\n\n' ) );
  76. },
  77. /**
  78. * Checks if given mixin i mixed to given class using {@link module:utils/mix mix} util.
  79. *
  80. * @param {Function} targetClass Class to check.
  81. * @param {Object} mixin Mixin to check.
  82. * @returns {Boolean} `True` when mixin is mixed to to target class, `false` otherwise.
  83. */
  84. isMixed( targetClass, mixin ) {
  85. let isValid = true;
  86. for ( const property in mixin ) {
  87. if ( Object.prototype.hasOwnProperty.call( mixin, property ) ) {
  88. if ( targetClass.prototype[ property ] !== mixin[ property ] ) {
  89. isValid = false;
  90. }
  91. }
  92. }
  93. return isValid;
  94. }
  95. };
  96. export default utils;