8
0

editor.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* bender-include: ../_tools/tools.js */
  6. 'use strict';
  7. const modules = bender.amd.require( 'editor', 'editorconfig', 'plugin' );
  8. let editor;
  9. let element;
  10. let asyncSpy;
  11. beforeEach( () => {
  12. const Editor = modules.editor;
  13. element = document.createElement( 'div' );
  14. document.body.appendChild( element );
  15. editor = new Editor( element );
  16. } );
  17. before( () => {
  18. // Define fake plugins to be used in tests.
  19. bender.tools.core.defineEditorCreatorMock( 'test', {
  20. init: sinon.spy().named( 'creator-test' )
  21. } );
  22. CKEDITOR.define( 'plugin!A', [ 'plugin' ], pluginDefinition( 'A' ) );
  23. CKEDITOR.define( 'plugin!B', [ 'plugin' ], pluginDefinition( 'B' ) );
  24. CKEDITOR.define( 'plugin!C', [ 'plugin', 'plugin!B' ], pluginDefinition( 'C' ) );
  25. CKEDITOR.define( 'plugin!D', [ 'plugin', 'plugin!C' ], pluginDefinition( 'D' ) );
  26. CKEDITOR.define( 'plugin!E', [ 'plugin' ], pluginDefinition( 'E' ) );
  27. // Synchronous plugin that depends on an asynchronous one.
  28. CKEDITOR.define( 'plugin!F', [ 'plugin', 'plugin!async' ], pluginDefinition( 'F' ) );
  29. asyncSpy = sinon.spy().named( 'async-call-spy' );
  30. CKEDITOR.define( 'plugin!async', [ 'plugin' ], ( Plugin ) => {
  31. class PluginAsync extends Plugin {}
  32. PluginAsync.prototype.init = sinon.spy( () => {
  33. return new Promise( ( resolve ) => {
  34. setTimeout( () => {
  35. asyncSpy();
  36. resolve();
  37. }, 0 );
  38. } );
  39. } );
  40. return PluginAsync;
  41. } );
  42. } );
  43. function pluginDefinition( name ) {
  44. return ( Plugin ) => {
  45. class NewPlugin extends Plugin {}
  46. NewPlugin.prototype.init = sinon.spy().named( name );
  47. return NewPlugin;
  48. };
  49. }
  50. ///////////////////
  51. describe( 'constructor', () => {
  52. it( 'should create a new editor instance', () => {
  53. expect( editor ).to.have.property( 'element' ).to.equal( element );
  54. } );
  55. } );
  56. describe( 'config', () => {
  57. it( 'should be an instance of EditorConfig', () => {
  58. const EditorConfig = modules.editorconfig;
  59. expect( editor.config ).to.be.an.instanceof( EditorConfig );
  60. } );
  61. } );
  62. describe( 'init', () => {
  63. it( 'should return a promise that resolves properly', () => {
  64. const Editor = modules.editor;
  65. editor = new Editor( element, {
  66. plugins: 'creator-test'
  67. } );
  68. let promise = editor.init();
  69. expect( promise ).to.be.an.instanceof( Promise );
  70. return promise;
  71. } );
  72. it( 'should fill `plugins`', () => {
  73. const Editor = modules.editor;
  74. const Plugin = modules.plugin;
  75. editor = new Editor( element, {
  76. plugins: 'A,B,creator-test'
  77. } );
  78. expect( editor.plugins.length ).to.equal( 0 );
  79. return editor.init().then( () => {
  80. expect( editor.plugins.length ).to.equal( 3 );
  81. expect( editor.plugins.get( 'A' ) ).to.be.an.instanceof( Plugin );
  82. expect( editor.plugins.get( 'B' ) ).to.be.an.instanceof( Plugin );
  83. expect( editor.plugins.get( 'creator-test' ) ).to.be.an.instanceof( Plugin );
  84. } );
  85. } );
  86. it( 'should initialize plugins in the right order', () => {
  87. const Editor = modules.editor;
  88. editor = new Editor( element, {
  89. plugins: 'creator-test,A,D'
  90. } );
  91. return editor.init().then( () => {
  92. sinon.assert.callOrder(
  93. editor.plugins.get( 'creator-test' ).init,
  94. editor.plugins.get( 'A' ).init,
  95. editor.plugins.get( 'B' ).init,
  96. editor.plugins.get( 'C' ).init,
  97. editor.plugins.get( 'D' ).init
  98. );
  99. } );
  100. } );
  101. it( 'should initialize plugins in the right order, waiting for asynchronous ones', () => {
  102. const Editor = modules.editor;
  103. editor = new Editor( element, {
  104. plugins: 'creator-test,A,F'
  105. } );
  106. return editor.init().then( () => {
  107. sinon.assert.callOrder(
  108. editor.plugins.get( 'creator-test' ).init,
  109. editor.plugins.get( 'A' ).init,
  110. editor.plugins.get( 'async' ).init,
  111. // This one is called with delay by the async init
  112. asyncSpy,
  113. editor.plugins.get( 'F' ).init
  114. );
  115. } );
  116. } );
  117. it( 'should not fail if loading a plugin that doesn\'t define init()', () => {
  118. const Editor = modules.editor;
  119. editor = new Editor( element, {
  120. plugins: 'E,creator-test'
  121. } );
  122. return editor.init();
  123. } );
  124. } );
  125. describe( 'plugins', () => {
  126. it( 'should be empty on new editor', () => {
  127. expect( editor.plugins.length ).to.equal( 0 );
  128. } );
  129. } );
  130. describe( 'destroy', () => {
  131. it( 'should fire "destroy"', () => {
  132. let spy = sinon.spy();
  133. editor.on( 'destroy', spy );
  134. return editor.destroy().then( () => {
  135. sinon.assert.called( spy );
  136. } );
  137. } );
  138. it( 'should delete the "element" property', () => {
  139. return editor.destroy().then( () => {
  140. expect( editor ).to.not.have.property( 'element' );
  141. } );
  142. } );
  143. } );