Kaynağa Gözat

Other: Merge configuration defined converters into one file.

Maciej Gołaszewski 8 yıl önce
ebeveyn
işleme
020b8b7c74

+ 0 - 39
packages/ckeditor5-engine/src/conversion/attributeelementconverters.js

@@ -1,39 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import AttributeElement from '../view/attributeelement';
-import buildModelConverter from './buildmodelconverter';
-import { defineConverter, parseDefinition } from './utils';
-
-/**
- * @param {String} attributeName
- * @param {} definition Converter definition
- * @param dispatchers
- */
-export function attributeElementToViewConverter( attributeName, definition, dispatchers ) {
-	const { model: attributeValue, viewDefinition } = parseDefinition( definition );
-
-	buildModelConverter()
-		.for( ...dispatchers )
-		.fromAttribute( attributeName )
-		.toElement( value => {
-			if ( value != attributeValue ) {
-				return;
-			}
-
-			return AttributeElement.fromViewDefinition( viewDefinition );
-		} );
-}
-
-export function viewToAttributeElementConverter( attributeName, definition, dispatchers ) {
-	const { model: attributeValue, viewDefinitions } = parseDefinition( definition );
-
-	const converter = defineConverter( dispatchers, viewDefinitions );
-
-	converter.toAttribute( () => ( {
-		key: attributeName,
-		value: attributeValue
-	} ) );
-}

+ 140 - 0
packages/ckeditor5-engine/src/conversion/configurationdefinedconverters.js

@@ -0,0 +1,140 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module engine/conversion/configurationdefinedconverters
+ */
+
+import AttributeElement from '../view/attributeelement';
+import ViewContainerElement from '../view/containerelement';
+
+import buildModelConverter from './buildmodelconverter';
+
+export function containerElementToView( definition, dispatchers ) {
+	const { model: modelElement, viewDefinition } = parseConverterDefinition( definition );
+
+	buildModelConverter()
+		.for( ...dispatchers )
+		.fromElement( modelElement )
+		.toElement( () => ViewContainerElement.fromViewDefinition( viewDefinition ) );
+}
+
+export function viewToContainerElement( definition, dispatchers ) {
+	const { model: modelElement, viewDefinitions } = parseConverterDefinition( definition );
+
+	const converter = defineViewConverter( dispatchers, viewDefinitions );
+
+	converter.toElement( modelElement );
+}
+
+/**
+ * Helper for creating model to view converter from model's attribute.
+ *
+ * @param {String} attributeName
+ * @param {} definition Converter definition
+ * @param dispatchers
+ */
+export function attributeElementToViewConverter( attributeName, definition, dispatchers ) {
+	const { model: attributeValue, viewDefinition } = parseConverterDefinition( definition );
+
+	buildModelConverter()
+		.for( ...dispatchers )
+		.fromAttribute( attributeName )
+		.toElement( value => {
+			if ( value != attributeValue ) {
+				return;
+			}
+
+			return AttributeElement.fromViewDefinition( viewDefinition );
+		} );
+}
+
+/**
+ *
+ * @param attributeName
+ * @param definition
+ * @param dispatchers
+ */
+export function viewToAttributeElementConverter( attributeName, definition, dispatchers ) {
+	const { model: attributeValue, viewDefinitions } = parseConverterDefinition( definition );
+
+	const converter = defineViewConverter( dispatchers, viewDefinitions );
+
+	converter.toAttribute( () => ( {
+		key: attributeName,
+		value: attributeValue
+	} ) );
+}
+
+import buildViewConverter from './buildviewconverter';
+
+// Prepares a {@link module:engine/conversion/utils~ConverterDefinition definition object} for building converters.
+//
+// @param {module:engine/conversion/utils~ConverterDefinition} definition An object that defines view to model and model to view conversion.
+// @returns {Object}
+function parseConverterDefinition( definition ) {
+	const model = definition.model;
+	const view = definition.view;
+
+	const viewDefinition = typeof view == 'string' ? { name: view } : view;
+
+	const viewDefinitions = definition.acceptsAlso ? definition.acceptsAlso : [];
+
+	viewDefinitions.push( viewDefinition );
+
+	return { model, viewDefinition, viewDefinitions };
+}
+
+// Helper method for preparing a view converter from passed view definitions.
+//
+// @param {Array.<module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher>} dispatchers
+// @param {Array.<module:engine/view/viewelementdefinition~ViewElementDefinition>} viewDefinitions
+// @returns {module:engine/conversion/buildviewconverter~ViewConverterBuilder}
+function defineViewConverter( dispatchers, viewDefinitions ) {
+	const converter = buildViewConverter().for( ...dispatchers );
+
+	for ( const viewDefinition of viewDefinitions ) {
+		converter.from( definitionToPattern( viewDefinition ) );
+
+		if ( viewDefinition.priority ) {
+			converter.withPriority( viewDefinition.priority );
+		}
+	}
+
+	return converter;
+}
+
+// Converts viewDefinition to a matcher pattern.
+// @param {module:engine/view/viewelementdefinition~ViewElementDefinition} viewDefinition
+// @returns {module:engine/view/matcher~Pattern}
+function definitionToPattern( viewDefinition ) {
+	const name = viewDefinition.name;
+	const classes = viewDefinition.classes;
+	const styles = viewDefinition.styles;
+	const attributes = viewDefinition.attributes;
+
+	const pattern = { name };
+
+	if ( classes ) {
+		pattern.class = classes;
+	}
+
+	if ( styles ) {
+		pattern.style = styles;
+	}
+
+	if ( attributes ) {
+		pattern.attribute = attributes;
+	}
+
+	return pattern;
+}
+
+/**
+ * @typedef {Object} ConvertedDefinition
+ * @property {String} model
+ * @property {String|module:engine/view/viewelementdefinition~ViewElementDefinition} view
+ * @property {Array.<module:engine/view/viewelementdefinition~ViewElementDefinition>} acceptAlso
+ */

+ 0 - 26
packages/ckeditor5-engine/src/conversion/containerelementconverters.js

@@ -1,26 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import buildModelConverter from './buildmodelconverter';
-import ViewContainerElement from '../view/containerelement';
-
-import { defineConverter, parseDefinition } from './utils';
-
-export function containerElementToView( definition, dispatchers ) {
-	const { model: modelElement, viewDefinition } = parseDefinition( definition );
-
-	buildModelConverter()
-		.for( ...dispatchers )
-		.fromElement( modelElement )
-		.toElement( () => ViewContainerElement.fromViewDefinition( viewDefinition ) );
-}
-
-export function viewToContainerElement( definition, dispatchers ) {
-	const { model: modelElement, viewDefinitions } = parseDefinition( definition );
-
-	const converter = defineConverter( dispatchers, viewDefinitions );
-
-	converter.toElement( modelElement );
-}

+ 0 - 54
packages/ckeditor5-engine/src/conversion/utils.js

@@ -1,54 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import buildViewConverter from './buildviewconverter';
-
-export function parseDefinition( definition ) {
-	const model = definition.model;
-	const view = definition.view;
-	const viewDefinition = typeof view == 'string' ? { name: view } : view;
-
-	const viewDefinitions = definition.acceptsAlso ? definition.acceptsAlso : [];
-
-	viewDefinitions.push( viewDefinition );
-
-	return { model, viewDefinition, viewDefinitions };
-}
-
-export function definitionToPattern( viewDefinition ) {
-	const name = viewDefinition.name;
-	const classes = viewDefinition.classes;
-	const styles = viewDefinition.styles;
-	const attributes = viewDefinition.attributes;
-
-	const pattern = { name };
-
-	if ( classes ) {
-		pattern.class = classes;
-	}
-
-	if ( styles ) {
-		pattern.style = styles;
-	}
-
-	if ( attributes ) {
-		pattern.attribute = attributes;
-	}
-
-	return pattern;
-}
-
-export function defineConverter( dispatchers, viewDefinitions ) {
-	const converter = buildViewConverter().for( ...dispatchers );
-
-	for ( const viewDefinition of viewDefinitions ) {
-		converter.from( definitionToPattern( viewDefinition ) );
-
-		if ( viewDefinition.priority ) {
-			converter.withPriority( viewDefinition.priority );
-		}
-	}
-	return converter;
-}

+ 5 - 5
packages/ckeditor5-engine/src/view/matcher.js

@@ -15,8 +15,8 @@ export default class Matcher {
 	/**
 	 * Creates new instance of Matcher.
 	 *
-	 * @param {String|RegExp|Object} [pattern] Match patterns. See {@link module:engine/view/matcher~Matcher#add add method} for
-	 * more information.
+	 * @param {String|RegExp|module:engine/view/matcher~Pattern} [pattern] Match patterns.
+	 * See {@link module:engine/view/matcher~Matcher#add add method} for more information.
 	 */
 	constructor( ...pattern ) {
 		this._patterns = [];
@@ -88,8 +88,8 @@ export default class Matcher {
 	 *
 	 * 		matcher.add( 'div', { class: 'foobar' } );
 	 *
-	 * @param {Object|String|RegExp|Function} pattern Object describing pattern details. If string or regular expression
-	 * is provided it will be used to match element's name. Pattern can be also provided in a form
+	 * @param {module:engine/view/matcher~Pattern|String|RegExp|Function} pattern Object describing pattern details.
+	 * If string or regular expression is provided it will be used to match element's name. Pattern can be also provided in a form
 	 * of a function - then this function will be called with each {@link module:engine/view/element~Element element} as a parameter.
 	 * Function's return value will be stored under `match` key of the object returned from
 	 * {@link module:engine/view/matcher~Matcher#match match} or {@link module:engine/view/matcher~Matcher#matchAll matchAll} methods.
@@ -380,7 +380,7 @@ function matchStyles( patterns, element ) {
 }
 
 /**
- * @typedef {Object} @module engine/view/matcher~Pattern
+ * @typedef {Object} Pattern
  *
  * @param {String|RegExp} [name] Name or regular expression to match element's name.
  * @param {Object} [attribute] Object with key-value pairs representing attributes to match. Each object key

+ 0 - 302
packages/ckeditor5-engine/tests/conversion/attributeelementconverters.js

@@ -1,302 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import ModelDocument from '../../src/model/document';
-import ModelElement from '../../src/model/element';
-import ModelText from '../../src/model/text';
-import ModelRange from '../../src/model/range';
-
-import ViewDocument from '../../src/view/document';
-import ViewElement from '../../src/view/element';
-import ViewAttributeElement from '../../src/view/attributeelement';
-import ViewText from '../../src/view/text';
-
-import Mapper from '../../src/conversion/mapper';
-import ModelConversionDispatcher from '../../src/conversion/modelconversiondispatcher';
-
-import {
-	insertText,
-	remove
-} from '../../src/conversion/model-to-view-converters';
-
-import { attributeElementToViewConverter, viewToAttributeElementConverter } from '../../src/conversion/attributeelementconverters';
-import { convertText } from '../../src/conversion/view-to-model-converters';
-import ViewConversionDispatcher from '../../src/conversion/viewconversiondispatcher';
-import ModelSchema from '../../src/model/schema';
-import ModelWalker from '../../src/model/treewalker';
-import ModelTextProxy from '../../src/model/textproxy';
-
-function viewAttributesToString( item ) {
-	let result = '';
-
-	for ( const key of item.getAttributeKeys() ) {
-		const value = item.getAttribute( key );
-
-		if ( value ) {
-			result += ' ' + key + '="' + value + '"';
-		}
-	}
-
-	return result;
-}
-
-function modelToString( item ) {
-	let result = '';
-
-	if ( item instanceof ModelTextProxy ) {
-		const attributes = modelAttributesToString( item );
-
-		result = attributes ? '<$text' + attributes + '>' + item.data + '</$text>' : item.data;
-	} else {
-		const walker = new ModelWalker( { boundaries: ModelRange.createIn( item ), shallow: true } );
-
-		for ( const value of walker ) {
-			result += modelToString( value.item );
-		}
-
-		if ( item instanceof ModelElement ) {
-			const attributes = modelAttributesToString( item );
-
-			result = '<' + item.name + attributes + '>' + result + '</' + item.name + '>';
-		}
-	}
-
-	return result;
-}
-
-function modelAttributesToString( item ) {
-	let result = '';
-
-	for ( const attr of item.getAttributes() ) {
-		result += ' ' + attr[ 0 ] + '="' + attr[ 1 ] + '"';
-	}
-
-	return result;
-}
-
-function viewToString( item ) {
-	let result = '';
-
-	if ( item instanceof ViewText ) {
-		result = item.data;
-	} else {
-		// ViewElement or ViewDocumentFragment.
-		for ( const child of item.getChildren() ) {
-			result += viewToString( child );
-		}
-
-		if ( item instanceof ViewElement ) {
-			result = '<' + item.name + viewAttributesToString( item ) + '>' + result + '</' + item.name + '>';
-		}
-	}
-
-	return result;
-}
-
-describe( 'Attribute converter', () => {
-	let dispatcher, mapper, modelDoc, modelRoot, viewDoc, viewRoot, viewSelection, batch;
-
-	beforeEach( () => {
-		modelDoc = new ModelDocument();
-		modelRoot = modelDoc.createRoot( 'root', 'root' );
-
-		batch = modelDoc.batch();
-
-		viewDoc = new ViewDocument();
-		viewRoot = viewDoc.createRoot( 'div' );
-		viewSelection = viewDoc.selection;
-
-		mapper = new Mapper();
-		mapper.bindElements( modelRoot, viewRoot );
-
-		dispatcher = new ModelConversionDispatcher( modelDoc, { mapper, viewSelection } );
-
-		dispatcher.on( 'insert:$text', insertText() );
-		dispatcher.on( 'remove', remove() );
-	} );
-
-	afterEach( () => {
-		viewDoc.destroy();
-	} );
-
-	function testConversion( definition, expectedConversion ) {
-		attributeElementToViewConverter( 'foo', definition, [ dispatcher ] );
-
-		const modelElement = new ModelText( 'foo', { foo: 'bar' } );
-		modelRoot.appendChildren( modelElement );
-
-		dispatcher.convertInsertion( ModelRange.createIn( modelRoot ) );
-
-		expect( viewToString( viewRoot ) ).to.equal( expectedConversion );
-
-		batch.removeAttribute( 'bold', modelRoot );
-
-		dispatcher.convertAttribute( 'removeAttribute', ModelRange.createIn( modelRoot ), 'foo', 'bar', null );
-
-		expect( viewToString( viewRoot ) ).to.equal( '<div>foo</div>' );
-	}
-
-	describe( 'model attribute to view element conversion', () => {
-		it( 'using passed view element name', () => {
-			testConversion( { model: 'bar', view: 'strong' }, '<div><strong>foo</strong></div>' );
-		} );
-
-		it( 'using passed view element object', () => {
-			testConversion( { model: 'bar', view: { name: 'strong' } }, '<div><strong>foo</strong></div>' );
-		} );
-
-		it( 'using passed view element object with styles object', () => {
-			testConversion( {
-				model: 'bar',
-				view: { name: 'span', styles: { 'font-weight': 'bold' } }
-			}, '<div><span style="font-weight:bold;">foo</span></div>' );
-		} );
-
-		it( 'using passed view element object with class string', () => {
-			testConversion( { model: 'bar', view: { name: 'span', classes: 'foo' } }, '<div><span class="foo">foo</span></div>' );
-		} );
-
-		it( 'using passed view element object with class array', () => {
-			testConversion( {
-				model: 'bar',
-				view: { name: 'span', classes: [ 'foo', 'foo-bar' ] }
-			}, '<div><span class="foo foo-bar">foo</span></div>' );
-		} );
-
-		it( 'using passed view element object with attributes', () => {
-			testConversion( {
-				model: 'bar',
-				view: { name: 'span', attributes: { 'data-foo': 'bar' } }
-			}, '<div><span data-foo="bar">foo</span></div>' );
-		} );
-
-		it( 'should do nothing for undefined value', () => {
-			attributeElementToViewConverter( 'foo', { model: 'bar', view: 'strong' }, [ dispatcher ] );
-
-			const modelElement = new ModelText( 'foo', { foo: 'baz' } );
-			modelRoot.appendChildren( modelElement );
-
-			dispatcher.convertInsertion( ModelRange.createIn( modelRoot ) );
-
-			expect( viewToString( viewRoot ) ).to.equal( '<div>foo</div>' );
-		} );
-	} );
-	describe( 'view element to model attribute conversion', () => {
-		let dispatcher, schema, additionalData, batch;
-
-		const modelDocument = new ModelDocument();
-
-		beforeEach( () => {
-			batch = modelDocument.batch();
-
-			// `additionalData` parameter for `.convert` calls.
-			additionalData = { context: [ '$root' ] };
-
-			schema = new ModelSchema();
-
-			schema.registerItem( 'div', '$block' );
-
-			schema.allow( { name: '$inline', attributes: [ 'foo' ], inside: '$root' } );
-			schema.allow( { name: '$text', inside: '$root' } );
-
-			dispatcher = new ViewConversionDispatcher( { schema } );
-			dispatcher.on( 'text', convertText() );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', { model: 'bar', view: 'strong' }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', { model: 'bar', view: { name: 'strong' } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', { model: 'bar', view: { name: 'span', classes: 'foo' } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'span', { class: 'foo' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', { model: 'bar', view: { name: 'span', classes: [ 'foo', 'bar' ] } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'span', { class: 'foo bar' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', {
-				model: 'bar',
-				view: { name: 'span', styles: { 'font-weight': 'bold' } }
-			}, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'span', { style: 'font-weight:bold' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', {
-				model: 'bar',
-				view: { name: 'span', attributes: { 'data-foo': 'bar' } }
-			}, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', {
-				model: 'bar',
-				view: 'strong',
-				acceptsAlso: [
-					{ name: 'span', classes: [ 'foo', 'bar' ] },
-					{ name: 'span', attributes: { 'data-foo': 'bar' } }
-				]
-			}, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToAttributeElementConverter( 'foo', { model: 'baz', view: 'strong' }, [ dispatcher ] );
-			viewToAttributeElementConverter( 'foo', { model: 'bar', view: { name: 'strong', priority: 'high' } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewAttributeElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
-		} );
-	} );
-} );

+ 472 - 0
packages/ckeditor5-engine/tests/conversion/configurationdefinedconverters.js

@@ -0,0 +1,472 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import ModelDocument from '../../src/model/document';
+import ModelElement from '../../src/model/element';
+import ModelText from '../../src/model/text';
+import ModelRange from '../../src/model/range';
+
+import ViewDocument from '../../src/view/document';
+import ViewElement from '../../src/view/element';
+import ViewAttributeElement from '../../src/view/attributeelement';
+import ViewText from '../../src/view/text';
+
+import Mapper from '../../src/conversion/mapper';
+import ModelConversionDispatcher from '../../src/conversion/modelconversiondispatcher';
+
+import { insertText, remove } from '../../src/conversion/model-to-view-converters';
+import { convertText } from '../../src/conversion/view-to-model-converters';
+
+import {
+	attributeElementToViewConverter,
+	viewToAttributeElementConverter,
+	containerElementToView,
+	viewToContainerElement
+} from '../../src/conversion/configurationdefinedconverters';
+
+import ViewConversionDispatcher from '../../src/conversion/viewconversiondispatcher';
+import ModelSchema from '../../src/model/schema';
+import ModelWalker from '../../src/model/treewalker';
+import ModelTextProxy from '../../src/model/textproxy';
+
+function viewAttributesToString( item ) {
+	let result = '';
+
+	for ( const key of item.getAttributeKeys() ) {
+		const value = item.getAttribute( key );
+
+		if ( value ) {
+			result += ' ' + key + '="' + value + '"';
+		}
+	}
+
+	return result;
+}
+
+function modelToString( item ) {
+	let result = '';
+
+	if ( item instanceof ModelTextProxy ) {
+		const attributes = modelAttributesToString( item );
+
+		result = attributes ? '<$text' + attributes + '>' + item.data + '</$text>' : item.data;
+	} else {
+		const walker = new ModelWalker( { boundaries: ModelRange.createIn( item ), shallow: true } );
+
+		for ( const value of walker ) {
+			result += modelToString( value.item );
+		}
+
+		if ( item instanceof ModelElement ) {
+			const attributes = modelAttributesToString( item );
+
+			result = '<' + item.name + attributes + '>' + result + '</' + item.name + '>';
+		}
+	}
+
+	return result;
+}
+
+function modelAttributesToString( item ) {
+	let result = '';
+
+	for ( const attr of item.getAttributes() ) {
+		result += ' ' + attr[ 0 ] + '="' + attr[ 1 ] + '"';
+	}
+
+	return result;
+}
+
+function viewToString( item ) {
+	let result = '';
+
+	if ( item instanceof ViewText ) {
+		result = item.data;
+	} else {
+		// ViewElement or ViewDocumentFragment.
+		for ( const child of item.getChildren() ) {
+			result += viewToString( child );
+		}
+
+		if ( item instanceof ViewElement ) {
+			result = '<' + item.name + viewAttributesToString( item ) + '>' + result + '</' + item.name + '>';
+		}
+	}
+
+	return result;
+}
+
+describe( 'Configuration defined converters', () => {
+	let dispatcher, mapper, modelDoc, modelRoot, viewDoc, viewRoot, viewSelection, batch;
+
+	beforeEach( () => {
+		modelDoc = new ModelDocument();
+		modelRoot = modelDoc.createRoot( 'root', 'root' );
+
+		batch = modelDoc.batch();
+
+		viewDoc = new ViewDocument();
+		viewRoot = viewDoc.createRoot( 'div' );
+		viewSelection = viewDoc.selection;
+
+		mapper = new Mapper();
+		mapper.bindElements( modelRoot, viewRoot );
+
+		dispatcher = new ModelConversionDispatcher( modelDoc, { mapper, viewSelection } );
+
+		dispatcher.on( 'insert:$text', insertText() );
+		dispatcher.on( 'remove', remove() );
+	} );
+
+	afterEach( () => {
+		viewDoc.destroy();
+	} );
+
+	describe( 'Attribute converter', () => {
+		function testConversion( definition, expectedConversion ) {
+			attributeElementToViewConverter( 'foo', definition, [ dispatcher ] );
+
+			const modelElement = new ModelText( 'foo', { foo: 'bar' } );
+			modelRoot.appendChildren( modelElement );
+
+			dispatcher.convertInsertion( ModelRange.createIn( modelRoot ) );
+
+			expect( viewToString( viewRoot ) ).to.equal( expectedConversion );
+
+			batch.removeAttribute( 'bold', modelRoot );
+
+			dispatcher.convertAttribute( 'removeAttribute', ModelRange.createIn( modelRoot ), 'foo', 'bar', null );
+
+			expect( viewToString( viewRoot ) ).to.equal( '<div>foo</div>' );
+		}
+
+		describe( 'model to view conversion', () => {
+			it( 'using passed view element name', () => {
+				testConversion( { model: 'bar', view: 'strong' }, '<div><strong>foo</strong></div>' );
+			} );
+
+			it( 'using passed view element object', () => {
+				testConversion( { model: 'bar', view: { name: 'strong' } }, '<div><strong>foo</strong></div>' );
+			} );
+
+			it( 'using passed view element object with styles object', () => {
+				testConversion( {
+					model: 'bar',
+					view: { name: 'span', styles: { 'font-weight': 'bold' } }
+				}, '<div><span style="font-weight:bold;">foo</span></div>' );
+			} );
+
+			it( 'using passed view element object with class string', () => {
+				testConversion( { model: 'bar', view: { name: 'span', classes: 'foo' } }, '<div><span class="foo">foo</span></div>' );
+			} );
+
+			it( 'using passed view element object with class array', () => {
+				testConversion( {
+					model: 'bar',
+					view: { name: 'span', classes: [ 'foo', 'foo-bar' ] }
+				}, '<div><span class="foo foo-bar">foo</span></div>' );
+			} );
+
+			it( 'using passed view element object with attributes', () => {
+				testConversion( {
+					model: 'bar',
+					view: { name: 'span', attributes: { 'data-foo': 'bar' } }
+				}, '<div><span data-foo="bar">foo</span></div>' );
+			} );
+
+			it( 'should do nothing for undefined value', () => {
+				attributeElementToViewConverter( 'foo', { model: 'bar', view: 'strong' }, [ dispatcher ] );
+
+				const modelElement = new ModelText( 'foo', { foo: 'baz' } );
+				modelRoot.appendChildren( modelElement );
+
+				dispatcher.convertInsertion( ModelRange.createIn( modelRoot ) );
+
+				expect( viewToString( viewRoot ) ).to.equal( '<div>foo</div>' );
+			} );
+		} );
+
+		describe( 'view to model conversion', () => {
+			let dispatcher, schema, additionalData, batch;
+
+			const modelDocument = new ModelDocument();
+
+			beforeEach( () => {
+				batch = modelDocument.batch();
+
+				// `additionalData` parameter for `.convert` calls.
+				additionalData = { context: [ '$root' ] };
+
+				schema = new ModelSchema();
+
+				schema.registerItem( 'div', '$block' );
+
+				schema.allow( { name: '$inline', attributes: [ 'foo' ], inside: '$root' } );
+				schema.allow( { name: '$text', inside: '$root' } );
+
+				dispatcher = new ViewConversionDispatcher( { schema } );
+				dispatcher.on( 'text', convertText() );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', { model: 'bar', view: 'strong' }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', { model: 'bar', view: { name: 'strong' } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', { model: 'bar', view: { name: 'span', classes: 'foo' } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'span', { class: 'foo' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', {
+					model: 'bar',
+					view: { name: 'span', classes: [ 'foo', 'bar' ] }
+				}, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'span', { class: 'foo bar' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', {
+					model: 'bar',
+					view: { name: 'span', styles: { 'font-weight': 'bold' } }
+				}, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'span', { style: 'font-weight:bold' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', {
+					model: 'bar',
+					view: { name: 'span', attributes: { 'data-foo': 'bar' } }
+				}, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', {
+					model: 'bar',
+					view: 'strong',
+					acceptsAlso: [
+						{ name: 'span', classes: [ 'foo', 'bar' ] },
+						{ name: 'span', attributes: { 'data-foo': 'bar' } }
+					]
+				}, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToAttributeElementConverter( 'foo', { model: 'baz', view: 'strong' }, [ dispatcher ] );
+				viewToAttributeElementConverter( 'foo', { model: 'bar', view: { name: 'strong', priority: 'high' } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewAttributeElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<$text foo="bar">foo</$text>' );
+			} );
+		} );
+	} );
+
+	describe( 'Element converter', () => {
+		function testModelConversion( definition, expectedResult ) {
+			containerElementToView( definition, [ dispatcher ] );
+
+			const modelElement = new ModelElement( 'foo', null, new ModelText( 'bar' ) );
+			modelRoot.appendChildren( modelElement );
+
+			dispatcher.convertInsertion( ModelRange.createIn( modelRoot ) );
+
+			expect( viewToString( viewRoot ) ).to.equal( '<div>' + expectedResult + '</div>' );
+		}
+
+		describe( 'model to view conversion', () => {
+			it( 'using passed view element name', () => {
+				testModelConversion( { model: 'foo', view: 'strong' }, '<strong>bar</strong>' );
+			} );
+
+			it( 'using passed view element object', () => {
+				testModelConversion( { model: 'foo', view: { name: 'strong' } }, '<strong>bar</strong>' );
+			} );
+
+			it( 'using passed view element object with styles object', () => {
+				testModelConversion( {
+					model: 'foo',
+					view: { name: 'span', styles: { 'font-weight': 'bold' } }
+				}, '<span style="font-weight:bold;">bar</span>' );
+			} );
+
+			it( 'using passed view element object with class string', () => {
+				testModelConversion( { model: 'foo', view: { name: 'span', classes: 'foo' } }, '<span class="foo">bar</span>' );
+			} );
+
+			it( 'using passed view element object with class array', () => {
+				testModelConversion( {
+					model: 'foo',
+					view: { name: 'span', classes: [ 'foo', 'foo-bar' ] }
+				}, '<span class="foo foo-bar">bar</span>' );
+			} );
+
+			it( 'using passed view element object with attributes', () => {
+				testModelConversion( {
+					model: 'foo',
+					view: { name: 'span', attributes: { 'data-foo': 'bar' } }
+				}, '<span data-foo="bar">bar</span>' );
+			} );
+		} );
+
+		describe( 'view to model conversion', () => {
+			let dispatcher, schema, additionalData, batch;
+
+			const modelDocument = new ModelDocument();
+
+			beforeEach( () => {
+				batch = modelDocument.batch();
+
+				// `additionalData` parameter for `.convert` calls.
+				additionalData = { context: [ '$root' ] };
+
+				schema = new ModelSchema();
+
+				schema.registerItem( 'div', '$block' );
+				schema.registerItem( 'bar', '$block' );
+				schema.registerItem( 'baz', '$block' );
+
+				schema.allow( { name: '$inline', attributes: [ 'foo' ], inside: '$root' } );
+				schema.allow( { name: '$text', inside: '$inline' } );
+
+				dispatcher = new ViewConversionDispatcher( { schema } );
+				dispatcher.on( 'text', convertText() );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( { model: 'bar', view: 'strong' }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( { model: 'bar', view: { name: 'strong' } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( { model: 'bar', view: { name: 'span', classes: 'foo' } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'span', { class: 'foo' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( { model: 'bar', view: { name: 'span', classes: [ 'foo', 'bar' ] } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'span', { class: 'foo bar' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( { model: 'bar', view: { name: 'span', styles: { 'font-weight': 'bold' } } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'span', { style: 'font-weight:bold' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( { model: 'bar', view: { name: 'span', attributes: { 'data-foo': 'bar' } } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( {
+					model: 'bar',
+					view: 'strong',
+					acceptsAlso: [
+						{ name: 'span', classes: [ 'foo', 'bar' ] },
+						{ name: 'span', attributes: { 'data-foo': 'bar' } }
+					]
+				}, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+
+			it( 'should convert from view element to model attribute', () => {
+				viewToContainerElement( { model: 'baz', view: 'strong' }, [ dispatcher ] );
+				viewToContainerElement( { model: 'bar', view: { name: 'strong', priority: 'high' } }, [ dispatcher ] );
+
+				const conversionResult = dispatcher.convert(
+					new ViewElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
+				);
+
+				expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
+			} );
+		} );
+	} );
+} );

+ 0 - 279
packages/ckeditor5-engine/tests/conversion/containerelementconverters.js

@@ -1,279 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import ModelDocument from '../../src/model/document';
-import ModelElement from '../../src/model/element';
-import ModelText from '../../src/model/text';
-import ModelRange from '../../src/model/range';
-
-import ViewDocument from '../../src/view/document';
-import ViewElement from '../../src/view/element';
-import ViewText from '../../src/view/text';
-
-import Mapper from '../../src/conversion/mapper';
-import ModelConversionDispatcher from '../../src/conversion/modelconversiondispatcher';
-
-import {
-	insertText,
-	remove
-} from '../../src/conversion/model-to-view-converters';
-
-import { containerElementToView, viewToContainerElement } from '../../src/conversion/containerelementconverters';
-import { convertText } from '../../src/conversion/view-to-model-converters';
-import ViewConversionDispatcher from '../../src/conversion/viewconversiondispatcher';
-import ModelSchema from '../../src/model/schema';
-import ModelWalker from '../../src/model/treewalker';
-import ModelTextProxy from '../../src/model/textproxy';
-
-function viewAttributesToString( item ) {
-	let result = '';
-
-	for ( const key of item.getAttributeKeys() ) {
-		const value = item.getAttribute( key );
-
-		if ( value ) {
-			result += ' ' + key + '="' + value + '"';
-		}
-	}
-
-	return result;
-}
-
-function modelToString( item ) {
-	let result = '';
-
-	if ( item instanceof ModelTextProxy ) {
-		const attributes = modelAttributesToString( item );
-
-		result = attributes ? '<$text' + attributes + '>' + item.data + '</$text>' : item.data;
-	} else {
-		const walker = new ModelWalker( { boundaries: ModelRange.createIn( item ), shallow: true } );
-
-		for ( const value of walker ) {
-			result += modelToString( value.item );
-		}
-
-		if ( item instanceof ModelElement ) {
-			const attributes = modelAttributesToString( item );
-
-			result = '<' + item.name + attributes + '>' + result + '</' + item.name + '>';
-		}
-	}
-
-	return result;
-}
-
-function modelAttributesToString( item ) {
-	let result = '';
-
-	for ( const attr of item.getAttributes() ) {
-		result += ' ' + attr[ 0 ] + '="' + attr[ 1 ] + '"';
-	}
-
-	return result;
-}
-
-function viewToString( item ) {
-	let result = '';
-
-	if ( item instanceof ViewText ) {
-		result = item.data;
-	} else {
-		// ViewElement or ViewDocumentFragment.
-		for ( const child of item.getChildren() ) {
-			result += viewToString( child );
-		}
-
-		if ( item instanceof ViewElement ) {
-			result = '<' + item.name + viewAttributesToString( item ) + '>' + result + '</' + item.name + '>';
-		}
-	}
-
-	return result;
-}
-
-describe( 'Element converter', () => {
-	let dispatcher, mapper, modelDoc, modelRoot, viewDoc, viewRoot, viewSelection;
-
-	beforeEach( () => {
-		modelDoc = new ModelDocument();
-		modelRoot = modelDoc.createRoot( 'root', 'root' );
-
-		viewDoc = new ViewDocument();
-		viewRoot = viewDoc.createRoot( 'div' );
-		viewSelection = viewDoc.selection;
-
-		mapper = new Mapper();
-		mapper.bindElements( modelRoot, viewRoot );
-
-		dispatcher = new ModelConversionDispatcher( modelDoc, { mapper, viewSelection } );
-
-		dispatcher.on( 'insert:$text', insertText() );
-		dispatcher.on( 'remove', remove() );
-	} );
-
-	afterEach( () => {
-		viewDoc.destroy();
-	} );
-
-	function testModelConversion( definition, expectedResult ) {
-		containerElementToView( definition, [ dispatcher ] );
-
-		const modelElement = new ModelElement( 'foo', null, new ModelText( 'bar' ) );
-		modelRoot.appendChildren( modelElement );
-
-		dispatcher.convertInsertion( ModelRange.createIn( modelRoot ) );
-
-		expect( viewToString( viewRoot ) ).to.equal( '<div>' + expectedResult + '</div>' );
-	}
-
-	describe( 'model element to view element conversion', () => {
-		it( 'using passed view element name', () => {
-			testModelConversion( { model: 'foo', view: 'strong' }, '<strong>bar</strong>' );
-		} );
-
-		it( 'using passed view element object', () => {
-			testModelConversion( { model: 'foo', view: { name: 'strong' } }, '<strong>bar</strong>' );
-		} );
-
-		it( 'using passed view element object with styles object', () => {
-			testModelConversion( {
-				model: 'foo',
-				view: { name: 'span', styles: { 'font-weight': 'bold' } }
-			}, '<span style="font-weight:bold;">bar</span>' );
-		} );
-
-		it( 'using passed view element object with class string', () => {
-			testModelConversion( { model: 'foo', view: { name: 'span', classes: 'foo' } }, '<span class="foo">bar</span>' );
-		} );
-
-		it( 'using passed view element object with class array', () => {
-			testModelConversion( {
-				model: 'foo',
-				view: { name: 'span', classes: [ 'foo', 'foo-bar' ] }
-			}, '<span class="foo foo-bar">bar</span>' );
-		} );
-
-		it( 'using passed view element object with attributes', () => {
-			testModelConversion( {
-				model: 'foo',
-				view: { name: 'span', attributes: { 'data-foo': 'bar' } }
-			}, '<span data-foo="bar">bar</span>' );
-		} );
-	} );
-
-	describe( 'view element to model element conversion', () => {
-		let dispatcher, schema, additionalData, batch;
-
-		const modelDocument = new ModelDocument();
-
-		beforeEach( () => {
-			batch = modelDocument.batch();
-
-			// `additionalData` parameter for `.convert` calls.
-			additionalData = { context: [ '$root' ] };
-
-			schema = new ModelSchema();
-
-			schema.registerItem( 'div', '$block' );
-			schema.registerItem( 'bar', '$block' );
-			schema.registerItem( 'baz', '$block' );
-
-			schema.allow( { name: '$inline', attributes: [ 'foo' ], inside: '$root' } );
-			schema.allow( { name: '$text', inside: '$inline' } );
-
-			dispatcher = new ViewConversionDispatcher( { schema } );
-			dispatcher.on( 'text', convertText() );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( { model: 'bar', view: 'strong' }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( { model: 'bar', view: { name: 'strong' } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( { model: 'bar', view: { name: 'span', classes: 'foo' } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'span', { class: 'foo' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( { model: 'bar', view: { name: 'span', classes: [ 'foo', 'bar' ] } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'span', { class: 'foo bar' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( { model: 'bar', view: { name: 'span', styles: { 'font-weight': 'bold' } } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'span', { style: 'font-weight:bold' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( { model: 'bar', view: { name: 'span', attributes: { 'data-foo': 'bar' } } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( {
-				model: 'bar',
-				view: 'strong',
-				acceptsAlso: [
-					{ name: 'span', classes: [ 'foo', 'bar' ] },
-					{ name: 'span', attributes: { 'data-foo': 'bar' } }
-				]
-			}, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'span', { 'data-foo': 'bar' }, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-
-		it( 'should convert from view element to model attribute', () => {
-			viewToContainerElement( { model: 'baz', view: 'strong' }, [ dispatcher ] );
-			viewToContainerElement( { model: 'bar', view: { name: 'strong', priority: 'high' } }, [ dispatcher ] );
-
-			const conversionResult = dispatcher.convert(
-				new ViewElement( 'strong', null, new ViewText( 'foo' ) ), batch, additionalData
-			);
-
-			expect( modelToString( conversionResult ) ).to.equal( '<bar>foo</bar>' );
-		} );
-	} );
-} );