|
@@ -6,214 +6,233 @@
|
|
|
import Context from '../src/context';
|
|
import Context from '../src/context';
|
|
|
import ContextPlugin from '../src/contextplugin';
|
|
import ContextPlugin from '../src/contextplugin';
|
|
|
import Plugin from '../src/plugin';
|
|
import Plugin from '../src/plugin';
|
|
|
|
|
+import Config from '@ckeditor/ckeditor5-utils/src/config';
|
|
|
|
|
+import Locale from '@ckeditor/ckeditor5-utils/src/locale';
|
|
|
import VirtualTestEditor from './_utils/virtualtesteditor';
|
|
import VirtualTestEditor from './_utils/virtualtesteditor';
|
|
|
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
|
|
|
|
|
|
describe( 'Context', () => {
|
|
describe( 'Context', () => {
|
|
|
- it( 'should share the same instance of plugin within editors using the same context', async () => {
|
|
|
|
|
- class ContextPluginA extends ContextPlugin {}
|
|
|
|
|
- class ContextPluginB extends ContextPlugin {}
|
|
|
|
|
- class EditorPluginA extends Plugin {}
|
|
|
|
|
|
|
+ describe( 'config', () => {
|
|
|
|
|
+ it( 'should be created', () => {
|
|
|
|
|
+ const context = new Context();
|
|
|
|
|
|
|
|
- const context = await Context.create( { plugins: [ ContextPluginA, ContextPluginB ] } );
|
|
|
|
|
- const editorA = await VirtualTestEditor.create( { context, plugins: [ ContextPluginA, EditorPluginA ] } );
|
|
|
|
|
- const editorB = await VirtualTestEditor.create( { context, plugins: [ ContextPluginB, EditorPluginA ] } );
|
|
|
|
|
|
|
+ expect( context.config ).to.instanceof( Config );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- expect( editorA.plugins.get( ContextPluginA ) ).to.equal( context.plugins.get( ContextPluginA ) );
|
|
|
|
|
- expect( editorA.plugins.has( ContextPluginB ) ).to.equal( false );
|
|
|
|
|
- expect( editorB.plugins.get( ContextPluginB ) ).to.equal( context.plugins.get( ContextPluginB ) );
|
|
|
|
|
- expect( editorB.plugins.has( ContextPluginA ) ).to.equal( false );
|
|
|
|
|
|
|
+ it( 'should be with given configuration', () => {
|
|
|
|
|
+ const context = new Context( { foo: 'bar' } );
|
|
|
|
|
|
|
|
- expect( context.plugins.has( EditorPluginA ) ).to.equal( false );
|
|
|
|
|
- expect( editorA.plugins.get( EditorPluginA ) ).to.not.equal( editorB.plugins.get( EditorPluginA ) );
|
|
|
|
|
-
|
|
|
|
|
- await context.destroy();
|
|
|
|
|
|
|
+ expect( context.config.get( 'foo' ) ).to.equal( 'bar' );
|
|
|
|
|
+ } );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
- it( 'should share the same instance of plugin (dependencies) within editors using the same context', async () => {
|
|
|
|
|
- class ContextPluginA extends ContextPlugin {}
|
|
|
|
|
- class ContextPluginB extends ContextPlugin {}
|
|
|
|
|
- class EditorPluginA extends Plugin {
|
|
|
|
|
- static get requires() {
|
|
|
|
|
- return [ ContextPluginA ];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- class EditorPluginB extends Plugin {
|
|
|
|
|
- static get requires() {
|
|
|
|
|
- return [ ContextPluginB ];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ describe( 'locale', () => {
|
|
|
|
|
+ it( 'is instantiated and t() is exposed', () => {
|
|
|
|
|
+ const context = new Context();
|
|
|
|
|
+
|
|
|
|
|
+ expect( context.locale ).to.be.instanceof( Locale );
|
|
|
|
|
+ expect( context.t ).to.equal( context.locale.t );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'is configured with the config.language (UI and the content)', () => {
|
|
|
|
|
+ const context = new Context( { language: 'pl' } );
|
|
|
|
|
+
|
|
|
|
|
+ expect( context.locale.uiLanguage ).to.equal( 'pl' );
|
|
|
|
|
+ expect( context.locale.contentLanguage ).to.equal( 'pl' );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'is configured with the config.language (different for UI and the content)', () => {
|
|
|
|
|
+ const context = new Context( { language: { ui: 'pl', content: 'ar' } } );
|
|
|
|
|
|
|
|
- const context = await Context.create( { plugins: [ ContextPluginA, ContextPluginB ] } );
|
|
|
|
|
- const editorA = await VirtualTestEditor.create( { context, plugins: [ EditorPluginA ] } );
|
|
|
|
|
- const editorB = await VirtualTestEditor.create( { context, plugins: [ EditorPluginB ] } );
|
|
|
|
|
|
|
+ expect( context.locale.uiLanguage ).to.equal( 'pl' );
|
|
|
|
|
+ expect( context.locale.contentLanguage ).to.equal( 'ar' );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- expect( context.plugins.get( ContextPluginA ) ).to.equal( editorA.plugins.get( ContextPluginA ) );
|
|
|
|
|
- expect( context.plugins.get( ContextPluginB ) ).to.equal( editorB.plugins.get( ContextPluginB ) );
|
|
|
|
|
|
|
+ it( 'is configured with the config.language (just the content)', () => {
|
|
|
|
|
+ const context = new Context( { language: { content: 'ar' } } );
|
|
|
|
|
|
|
|
- await context.destroy();
|
|
|
|
|
|
|
+ expect( context.locale.uiLanguage ).to.equal( 'en' );
|
|
|
|
|
+ expect( context.locale.contentLanguage ).to.equal( 'ar' );
|
|
|
|
|
+ } );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
- it( 'should not initialize twice plugin added to the context and the editor', async () => {
|
|
|
|
|
- const initSpy = sinon.spy();
|
|
|
|
|
- const afterInitSpy = sinon.spy();
|
|
|
|
|
|
|
+ describe( 'plugins', () => {
|
|
|
|
|
+ it( 'should throw when plugin added to the context is not marked as a ContextPlugin #1', async () => {
|
|
|
|
|
+ class EditorPlugin extends Plugin {}
|
|
|
|
|
|
|
|
- class ContextPluginA extends ContextPlugin {
|
|
|
|
|
- init() {
|
|
|
|
|
- initSpy();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ let caughtError;
|
|
|
|
|
|
|
|
- afterInit() {
|
|
|
|
|
- afterInitSpy();
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ await Context.create( { plugins: [ EditorPlugin ] } );
|
|
|
|
|
+ } catch ( error ) {
|
|
|
|
|
+ caughtError = error;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const context = await Context.create( { plugins: [ ContextPluginA ] } );
|
|
|
|
|
- const editor = await VirtualTestEditor.create( { context, plugins: [ ContextPluginA ] } );
|
|
|
|
|
|
|
|
|
|
- expect( context.plugins.get( ContextPluginA ) ).to.equal( editor.plugins.get( ContextPluginA ) );
|
|
|
|
|
- sinon.assert.calledOnce( initSpy );
|
|
|
|
|
- sinon.assert.calledOnce( afterInitSpy );
|
|
|
|
|
|
|
+ expect( caughtError ).to.instanceof( CKEditorError );
|
|
|
|
|
+ expect( caughtError.message ).match( /^context-initplugins: Only plugins marked as a ContextPlugin are allowed./ );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- await context.destroy();
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ it( 'should throw when plugin added to the context is not marked as a ContextPlugin #2', async () => {
|
|
|
|
|
+ function EditorPlugin() {}
|
|
|
|
|
|
|
|
- it( 'should not destroy context along with the editor when context is injected to the editor', async () => {
|
|
|
|
|
- const contextPluginDestroySpy = sinon.spy();
|
|
|
|
|
- const editorPluginDestroySpy = sinon.spy();
|
|
|
|
|
|
|
+ let caughtError;
|
|
|
|
|
|
|
|
- class ContextPluginA extends ContextPlugin {
|
|
|
|
|
- destroy() {
|
|
|
|
|
- contextPluginDestroySpy();
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ await Context.create( { plugins: [ EditorPlugin ] } );
|
|
|
|
|
+ } catch ( error ) {
|
|
|
|
|
+ caughtError = error;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- class EditorPlugin extends Plugin {
|
|
|
|
|
- destroy() {
|
|
|
|
|
- editorPluginDestroySpy();
|
|
|
|
|
|
|
+ expect( caughtError ).to.instanceof( CKEditorError );
|
|
|
|
|
+ expect( caughtError.message ).match( /^context-initplugins: Only plugins marked as a ContextPlugin are allowed./ );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'should throw when plugin is added to the context by name', async () => {
|
|
|
|
|
+ let caughtError;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ await Context.create( { plugins: [ 'ContextPlugin' ] } );
|
|
|
|
|
+ } catch ( error ) {
|
|
|
|
|
+ caughtError = error;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- const context = await Context.create( { plugins: [ ContextPluginA ] } );
|
|
|
|
|
- const editor = await VirtualTestEditor.create( { context, plugins: [ ContextPluginA, EditorPlugin ] } );
|
|
|
|
|
|
|
+ expect( caughtError ).to.instanceof( CKEditorError );
|
|
|
|
|
+ expect( caughtError.message ).match( /^context-initplugins: Only constructor is allowed as a Context plugin./ );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- await editor.destroy();
|
|
|
|
|
|
|
+ it( 'should not throw when plugin as a function, marked as a ContextPlugin is added to the context', async () => {
|
|
|
|
|
+ function EditorPlugin() {}
|
|
|
|
|
+ EditorPlugin.isContextPlugin = true;
|
|
|
|
|
|
|
|
- sinon.assert.calledOnce( editorPluginDestroySpy );
|
|
|
|
|
- sinon.assert.notCalled( contextPluginDestroySpy );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ let caughtError;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ await Context.create( { plugins: [ EditorPlugin ] } );
|
|
|
|
|
+ } catch ( error ) {
|
|
|
|
|
+ caughtError = error;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- it( 'should destroy all editors with injected context when context is destroyed', async () => {
|
|
|
|
|
- const context = await Context.create();
|
|
|
|
|
- const editorA = await VirtualTestEditor.create( { context } );
|
|
|
|
|
- const editorB = await VirtualTestEditor.create( { context } );
|
|
|
|
|
- const editorC = await VirtualTestEditor.create();
|
|
|
|
|
|
|
+ expect( caughtError ).to.equal( undefined );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- sinon.spy( editorA, 'destroy' );
|
|
|
|
|
- sinon.spy( editorB, 'destroy' );
|
|
|
|
|
- sinon.spy( editorC, 'destroy' );
|
|
|
|
|
|
|
+ it( 'should share the same instance of plugin within editors using the same context', async () => {
|
|
|
|
|
+ class ContextPluginA extends ContextPlugin {}
|
|
|
|
|
+ class ContextPluginB extends ContextPlugin {}
|
|
|
|
|
+ class EditorPluginA extends Plugin {}
|
|
|
|
|
|
|
|
- await context.destroy();
|
|
|
|
|
|
|
+ const context = await Context.create( { plugins: [ ContextPluginA, ContextPluginB ] } );
|
|
|
|
|
+ const editorA = await VirtualTestEditor.create( { context, plugins: [ ContextPluginA, EditorPluginA ] } );
|
|
|
|
|
+ const editorB = await VirtualTestEditor.create( { context, plugins: [ ContextPluginB, EditorPluginA ] } );
|
|
|
|
|
|
|
|
- sinon.assert.calledOnce( editorA.destroy );
|
|
|
|
|
- sinon.assert.calledOnce( editorB.destroy );
|
|
|
|
|
- sinon.assert.notCalled( editorC.destroy );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ expect( editorA.plugins.get( ContextPluginA ) ).to.equal( context.plugins.get( ContextPluginA ) );
|
|
|
|
|
+ expect( editorA.plugins.has( ContextPluginB ) ).to.equal( false );
|
|
|
|
|
+ expect( editorB.plugins.get( ContextPluginB ) ).to.equal( context.plugins.get( ContextPluginB ) );
|
|
|
|
|
+ expect( editorB.plugins.has( ContextPluginA ) ).to.equal( false );
|
|
|
|
|
|
|
|
- it( 'should be able to add context plugin to the editor using pluginName property', async () => {
|
|
|
|
|
- class ContextPluginA extends ContextPlugin {
|
|
|
|
|
- static get pluginName() {
|
|
|
|
|
- return 'ContextPluginA';
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ expect( context.plugins.has( EditorPluginA ) ).to.equal( false );
|
|
|
|
|
+ expect( editorA.plugins.get( EditorPluginA ) ).to.not.equal( editorB.plugins.get( EditorPluginA ) );
|
|
|
|
|
|
|
|
- class ContextPluginB extends ContextPlugin {
|
|
|
|
|
- static get pluginName() {
|
|
|
|
|
- return 'ContextPluginB';
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ await context.destroy();
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- static get requires() {
|
|
|
|
|
- return [ ContextPluginA ];
|
|
|
|
|
|
|
+ it( 'should share the same instance of plugin (dependencies) within editors using the same context', async () => {
|
|
|
|
|
+ class ContextPluginA extends ContextPlugin {}
|
|
|
|
|
+ class ContextPluginB extends ContextPlugin {}
|
|
|
|
|
+ class EditorPluginA extends Plugin {
|
|
|
|
|
+ static get requires() {
|
|
|
|
|
+ return [ ContextPluginA ];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ class EditorPluginB extends Plugin {
|
|
|
|
|
+ static get requires() {
|
|
|
|
|
+ return [ ContextPluginB ];
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- const context = await Context.create( { plugins: [ ContextPluginB ] } );
|
|
|
|
|
- const editor = await VirtualTestEditor.create( { context, plugins: [ 'ContextPluginA' ] } );
|
|
|
|
|
|
|
+ const context = await Context.create( { plugins: [ ContextPluginA, ContextPluginB ] } );
|
|
|
|
|
+ const editorA = await VirtualTestEditor.create( { context, plugins: [ EditorPluginA ] } );
|
|
|
|
|
+ const editorB = await VirtualTestEditor.create( { context, plugins: [ EditorPluginB ] } );
|
|
|
|
|
|
|
|
- expect( editor.plugins.has( ContextPluginA ) ).to.equal( true );
|
|
|
|
|
- expect( editor.plugins.has( ContextPluginB ) ).to.equal( false );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ expect( context.plugins.get( ContextPluginA ) ).to.equal( editorA.plugins.get( ContextPluginA ) );
|
|
|
|
|
+ expect( context.plugins.get( ContextPluginB ) ).to.equal( editorB.plugins.get( ContextPluginB ) );
|
|
|
|
|
|
|
|
- it( 'should throw when plugin is added to the context by name', async () => {
|
|
|
|
|
- let caughtError;
|
|
|
|
|
|
|
+ await context.destroy();
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- await Context.create( { plugins: [ 'ContextPlugin' ] } );
|
|
|
|
|
- } catch ( error ) {
|
|
|
|
|
- caughtError = error;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ it( 'should not initialize twice plugin added to the context and the editor', async () => {
|
|
|
|
|
+ const initSpy = sinon.spy();
|
|
|
|
|
+ const afterInitSpy = sinon.spy();
|
|
|
|
|
|
|
|
- expect( caughtError ).to.instanceof( CKEditorError );
|
|
|
|
|
- expect( caughtError.message ).match( /^context-initplugins: Only constructor is allowed as a Context plugin./ );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ class ContextPluginA extends ContextPlugin {
|
|
|
|
|
+ init() {
|
|
|
|
|
+ initSpy();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- it( 'should throw when plugin added to the context is not marked as a ContextPlugin #1', async () => {
|
|
|
|
|
- class EditorPlugin extends Plugin {}
|
|
|
|
|
|
|
+ afterInit() {
|
|
|
|
|
+ afterInitSpy();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- let caughtError;
|
|
|
|
|
|
|
+ const context = await Context.create( { plugins: [ ContextPluginA ] } );
|
|
|
|
|
+ const editor = await VirtualTestEditor.create( { context, plugins: [ ContextPluginA ] } );
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- await Context.create( { plugins: [ EditorPlugin ] } );
|
|
|
|
|
- } catch ( error ) {
|
|
|
|
|
- caughtError = error;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ expect( context.plugins.get( ContextPluginA ) ).to.equal( editor.plugins.get( ContextPluginA ) );
|
|
|
|
|
+ sinon.assert.calledOnce( initSpy );
|
|
|
|
|
+ sinon.assert.calledOnce( afterInitSpy );
|
|
|
|
|
|
|
|
- expect( caughtError ).to.instanceof( CKEditorError );
|
|
|
|
|
- expect( caughtError.message ).match( /^context-initplugins: Only plugins marked as a ContextPlugin are allowed./ );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ await context.destroy();
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- it( 'should throw when plugin added to the context is not marked as a ContextPlugin #2', async () => {
|
|
|
|
|
- function EditorPlugin() {}
|
|
|
|
|
|
|
+ it( 'should be able to add context plugin to the editor using pluginName property', async () => {
|
|
|
|
|
+ class ContextPluginA extends ContextPlugin {
|
|
|
|
|
+ static get pluginName() {
|
|
|
|
|
+ return 'ContextPluginA';
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- let caughtError;
|
|
|
|
|
|
|
+ class ContextPluginB extends ContextPlugin {
|
|
|
|
|
+ static get pluginName() {
|
|
|
|
|
+ return 'ContextPluginB';
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- await Context.create( { plugins: [ EditorPlugin ] } );
|
|
|
|
|
- } catch ( error ) {
|
|
|
|
|
- caughtError = error;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ static get requires() {
|
|
|
|
|
+ return [ ContextPluginA ];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- expect( caughtError ).to.instanceof( CKEditorError );
|
|
|
|
|
- expect( caughtError.message ).match( /^context-initplugins: Only plugins marked as a ContextPlugin are allowed./ );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ const context = await Context.create( { plugins: [ ContextPluginB ] } );
|
|
|
|
|
+ const editor = await VirtualTestEditor.create( { context, plugins: [ 'ContextPluginA' ] } );
|
|
|
|
|
|
|
|
- it( 'should not throw when plugin added to the context has not a ContextPlugin proto but is marked as a ContextPlugin', async () => {
|
|
|
|
|
- function EditorPlugin() {}
|
|
|
|
|
- EditorPlugin.isContextPlugin = true;
|
|
|
|
|
|
|
+ expect( editor.plugins.has( ContextPluginA ) ).to.equal( true );
|
|
|
|
|
+ expect( editor.plugins.has( ContextPluginB ) ).to.equal( false );
|
|
|
|
|
+ } );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- let caughtError;
|
|
|
|
|
|
|
+ describe( 'destroy()', () => {
|
|
|
|
|
+ it( 'should destroy plugins', async () => {
|
|
|
|
|
+ const context = await Context.create();
|
|
|
|
|
+ const spy = sinon.spy( context.plugins, 'destroy' );
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- await Context.create( { plugins: [ EditorPlugin ] } );
|
|
|
|
|
- } catch ( error ) {
|
|
|
|
|
- caughtError = error;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ await context.destroy();
|
|
|
|
|
|
|
|
- expect( caughtError ).to.equal( undefined );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ sinon.assert.calledOnce( spy );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- it( 'should throw when plugin added to the context is not marked as a ContextPlugin #2', async () => {
|
|
|
|
|
- function EditorPlugin() {}
|
|
|
|
|
|
|
+ it( 'should destroy all editors with injected context', async () => {
|
|
|
|
|
+ const context = await Context.create();
|
|
|
|
|
+ const editorA = await VirtualTestEditor.create( { context } );
|
|
|
|
|
+ const editorB = await VirtualTestEditor.create( { context } );
|
|
|
|
|
+ const editorC = await VirtualTestEditor.create();
|
|
|
|
|
|
|
|
- let caughtError;
|
|
|
|
|
|
|
+ sinon.spy( editorA, 'destroy' );
|
|
|
|
|
+ sinon.spy( editorB, 'destroy' );
|
|
|
|
|
+ sinon.spy( editorC, 'destroy' );
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- await Context.create( { plugins: [ EditorPlugin ] } );
|
|
|
|
|
- } catch ( error ) {
|
|
|
|
|
- caughtError = error;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ await context.destroy();
|
|
|
|
|
|
|
|
- expect( caughtError ).to.instanceof( CKEditorError );
|
|
|
|
|
- expect( caughtError.message ).match( /^context-initplugins: Only plugins marked as a ContextPlugin are allowed./ );
|
|
|
|
|
|
|
+ sinon.assert.calledOnce( editorA.destroy );
|
|
|
|
|
+ sinon.assert.calledOnce( editorB.destroy );
|
|
|
|
|
+ sinon.assert.notCalled( editorC.destroy );
|
|
|
|
|
+ } );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|