editor.js 4.7 KB

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