creator.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. /* bender-include: ../_tools/tools.js */
  7. const modules = bender.amd.require( 'editor', 'plugin', 'creator', 'ckeditorerror' );
  8. let editor, element;
  9. function initEditor( config ) {
  10. const Editor = modules.editor;
  11. element = document.createElement( 'div' );
  12. document.body.appendChild( element );
  13. editor = new Editor( element, config );
  14. return editor.init();
  15. }
  16. bender.tools.createSinonSandbox();
  17. before( () => {
  18. bender.tools.core.defineEditorCreatorMock( 'test1' );
  19. bender.tools.core.defineEditorCreatorMock( 'test-any1' );
  20. bender.tools.core.defineEditorCreatorMock( 'test-any2' );
  21. bender.tools.core.defineEditorCreatorMock( 'test-config1' );
  22. bender.tools.core.defineEditorCreatorMock( 'test-config2' );
  23. CKEDITOR.define( 'plugin!test3', [ 'plugin' ], ( Plugin ) => {
  24. return class extends Plugin {};
  25. } );
  26. CKEDITOR.define( 'plugin!creator-async-create', [ 'creator' ], ( Creator ) => {
  27. return class extends Creator {
  28. create() {
  29. return new Promise( ( resolve, reject ) => {
  30. reject( new Error( 'Catch me - create.' ) );
  31. } );
  32. }
  33. destroy() {}
  34. };
  35. } );
  36. CKEDITOR.define( 'plugin!creator-async-destroy', [ 'creator' ], ( Creator ) => {
  37. return class extends Creator {
  38. create() {}
  39. destroy() {
  40. return new Promise( ( resolve, reject ) => {
  41. reject( new Error( 'Catch me - destroy.' ) );
  42. } );
  43. }
  44. };
  45. } );
  46. } );
  47. afterEach( () => {
  48. editor = null; // To make sure we're using the freshly inited editor.
  49. } );
  50. ///////////////////
  51. describe( 'init', () => {
  52. it( 'should instantiate the creator and call create()', () => {
  53. const Creator = modules.creator;
  54. return initEditor( {
  55. plugins: 'creator-test1'
  56. } )
  57. .then( () => {
  58. let creator = editor.plugins.get( 'creator-test1' );
  59. expect( creator ).to.be.instanceof( Creator );
  60. // The create method has been called.
  61. sinon.assert.calledOnce( creator.create );
  62. } );
  63. } );
  64. it( 'should instantiate any creator when more than one is available', () => {
  65. return initEditor( {
  66. plugins: 'creator-test-any1,creator-test-any2'
  67. } )
  68. .then( () => {
  69. let creator1 = editor.plugins.get( 'creator-test-any1' );
  70. let creator2 = editor.plugins.get( 'creator-test-any2' );
  71. expect( creator1.create.called + creator2.create.called ).to.be.equal( 1, 'only one of the creators should be used' );
  72. } );
  73. } );
  74. it( 'should use the creator specified in config.creator', () => {
  75. return initEditor( {
  76. creator: 'test-config2',
  77. plugins: 'creator-test-config1,creator-test-config2',
  78. } )
  79. .then( () => {
  80. let creator1 = editor.plugins.get( 'creator-test-config1' );
  81. let creator2 = editor.plugins.get( 'creator-test-config2' );
  82. sinon.assert.calledOnce( creator2.create );
  83. sinon.assert.notCalled( creator1.create );
  84. } );
  85. } );
  86. it( 'should throw an error if the creator doesn\'t exist', () => {
  87. let CKEditorError = modules.ckeditorerror;
  88. return initEditor( {
  89. creator: 'bad',
  90. plugins: 'creator-test1'
  91. } )
  92. .then( () => {
  93. throw new Error( 'This should not be executed.' );
  94. } )
  95. .catch( ( err ) => {
  96. expect( err ).to.be.instanceof( CKEditorError );
  97. expect( err.message ).to.match( /^editor-creator-404:/ );
  98. } );
  99. } );
  100. it( 'should throw an error no creators are defined', () => {
  101. const CKEditorError = modules.ckeditorerror;
  102. return initEditor( {} )
  103. .then( () => {
  104. throw new Error( 'This should not be executed.' );
  105. } )
  106. .catch( ( err ) => {
  107. expect( err ).to.be.instanceof( CKEditorError );
  108. expect( err.message ).to.match( /^editor-creator-404:/ );
  109. } );
  110. } );
  111. it( 'should chain the promise from the creator (enables async creators)', () => {
  112. return initEditor( {
  113. plugins: 'creator-async-create'
  114. } )
  115. .then( () => {
  116. throw new Error( 'This should not be executed.' );
  117. } )
  118. .catch( ( err ) => {
  119. // Unfortunately fake timers don't work with promises, so throwing in the creator's create()
  120. // seems to be the only way to test that the promise chain isn't broken.
  121. expect( err ).to.have.property( 'message', 'Catch me - create.' );
  122. } );
  123. } );
  124. } );
  125. describe( 'destroy', () => {
  126. it( 'should call "destroy" on the creator', () => {
  127. let creator1;
  128. return initEditor( {
  129. plugins: 'creator-test1'
  130. } )
  131. .then( () => {
  132. creator1 = editor.plugins.get( 'creator-test1' );
  133. return editor.destroy();
  134. } )
  135. .then( () => {
  136. sinon.assert.calledOnce( creator1.destroy );
  137. } );
  138. } );
  139. it( 'should chain the promise from the creator (enables async creators)', () => {
  140. return initEditor( {
  141. plugins: 'creator-async-destroy'
  142. } )
  143. .then( () => {
  144. return editor.destroy();
  145. } )
  146. .then( () => {
  147. throw new Error( 'This should not be executed.' );
  148. } )
  149. .catch( ( err ) => {
  150. // Unfortunately fake timers don't work with promises, so throwing in the creator's destroy()
  151. // seems to be the only way to test that the promise chain isn't broken.
  152. expect( err ).to.have.property( 'message', 'Catch me - destroy.' );
  153. } );
  154. } );
  155. } );