8
0
Просмотр исходного кода

Merge branch 'master' into i/7444-2SCM-refactor-highlight

Tomek Wytrębowicz 5 лет назад
Родитель
Сommit
f9b33f0177

+ 13 - 0
docs/framework/guides/contributing/code-style.md

@@ -510,6 +510,19 @@ There are some special rules and tips for tests.
 
 	Think about this — when you fix a bug by adding a parameter to an existing function call you do not affect code coverage (that line was called anyway). However, you had a bug, meaning that your test suite did not cover it. Therefore, a test must be created for that code change.
 * It should be `expect( x ).to.equal( y )`. **NOT**: ~~`expect( x ).to.be.equal( y )`~~.
+* When using Sinon spies, pay attention to the readability of assertions and failure messages.
+   * Use named spies, for example:
+
+		```js
+		const someCallbackSpy = sinon.spy().named( 'someCallback' );
+		const myMethodSpy = sinon.spy( obj, 'myMethod' );
+		```
+   * Use [sinon-chai assertions](https://www.chaijs.com/plugins/sinon-chai/)
+
+		```js
+		expect( myMethodSpy ).to.be.calledOnce 
+		// expected myMethod to be called once but was called twice
+		```
 
 ## Naming
 

+ 79 - 0
packages/ckeditor5-core/tests/_utils-tests/assertions/attribute.js

@@ -0,0 +1,79 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* global chai */
+
+import '../../_utils/assertions/attribute';
+
+describe( 'attribute chai assertion', () => {
+	it( 'should be added to chai assertions', () => {
+		const assertion = new chai.Assertion();
+
+		expect( assertion ).to.have.property( 'attribute' );
+		expect( assertion.attribute ).to.be.instanceof( Function );
+	} );
+
+	it( 'should assert the target has a \'hasAttribute\' method', () => {
+		expect( { hasAttribute: () => true } ).to.have.attribute( 'foo' );
+
+		expect( function() {
+			expect( {} ).not.to.have.attribute( 'bar' );
+		} ).to.throw( 'expected {} to respond to \'hasAttribute\'' );
+
+		expect( function() {
+			expect( {} ).to.have.attribute( 'bar' );
+		} ).to.throw( 'expected {} to respond to \'hasAttribute\'' );
+	} );
+
+	it( 'should assert the \'target.hasAttribute\' returns \'true\' for the given type', () => {
+		expect( { hasAttribute: () => true } ).to.have.attribute( 'foo' );
+
+		expect( function() {
+			expect( { hasAttribute: () => false } ).to.have.attribute( 'bar' );
+		} ).to.throw( 'expected { Object (hasAttribute) } to have attribute \'bar\'' );
+	} );
+
+	it( 'negated, should assert the \'target.hasAttribute\' returns \'false\' for the given type', () => {
+		expect( { hasAttribute: () => false } ).not.to.have.attribute( 'foo' );
+
+		expect( function() {
+			expect( { hasAttribute: () => true } ).not.to.have.attribute( 'bar' );
+		} ).to.throw( 'expected { Object (hasAttribute) } to not have attribute \'bar\'' );
+	} );
+
+	it( 'should assert the \'target.getAttribute\' returns the given value for the given type', () => {
+		expect( {
+			hasAttribute: () => true,
+			getAttribute: () => 'bar'
+		} ).to.have.attribute( 'foo', 'bar' );
+
+		expect( function() {
+			expect( {
+				hasAttribute: () => true,
+				getAttribute: () => 'bar'
+			} ).to.have.attribute( 'foo', 'baz' );
+		} ).to.throw( 'expected { Object (hasAttribute, getAttribute) } to have attribute \'foo\' of \'bar\', but got \'baz\'' );
+	} );
+
+	it( 'negated, should assert for the given type the \'target.getAttribute\' returns a value different than the given one', () => {
+		expect( {
+			hasAttribute: () => true,
+			getAttribute: () => 'bar'
+		} ).to.not.have.attribute( 'foo', 'baz' );
+
+		expect( function() {
+			expect( {
+				hasAttribute: () => true,
+				getAttribute: () => 'baz'
+			} ).to.not.have.attribute( 'foo', 'baz' );
+		} ).to.throw( 'expected { Object (hasAttribute, getAttribute) } to not have attribute \'foo\' of \'baz\'' );
+	} );
+
+	it( 'should prefix failure message with the given one', () => {
+		expect( function() {
+			expect( {} ).to.have.attribute( 'foo', 'baz', 'Illegal salmon' );
+		} ).to.throw( /^Illegal salmon: / );
+	} );
+} );

+ 61 - 0
packages/ckeditor5-core/tests/_utils/assertions/attribute.js

@@ -0,0 +1,61 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* global chai */
+
+/**
+ * Asserts that the target has an attribute with the given key name.
+ * See {@link module:engine/model/documentselection~DocumentSelection#hasAttribute hasAttribute}.
+ *
+ *		expect( selection ).to.have.attribute( 'linkHref' );
+ *
+ * When `value` is provided, .attribute also asserts that the attribute's value is equal to the given `value`.
+ * See {@link module:engine/model/documentselection~DocumentSelection#getAttribute getAttribute}.
+ *
+ *		expect( selection ).to.have.attribute( 'linkHref', 'example.com' );
+ *
+ * Negations works as well.
+ *
+ * @param {String} key Key of attribute to assert.
+ * @param {String} [value] Attribute value to assert.
+ * @param {String} [message] Additional message.
+ */
+chai.Assertion.addMethod( 'attribute', function attributeAssertion( key, value, message ) {
+	if ( message ) {
+		chai.util.flag( this, 'message', message );
+	}
+
+	const obj = this._obj;
+
+	if ( arguments.length === 1 ) {
+		// Check if it has the method at all.
+		new chai.Assertion( obj ).to.respondTo( 'hasAttribute' );
+
+		// Check if it has the attribute.
+		const hasAttribute = obj.hasAttribute( key );
+		this.assert(
+			hasAttribute === true,
+			`expected #{this} to have attribute '${ key }'`,
+			`expected #{this} to not have attribute '${ key }'`,
+			!chai.util.flag( this, 'negate' ),
+			hasAttribute
+		);
+	}
+
+	// If a value was given.
+	if ( arguments.length >= 2 ) {
+		// Check if it has the method at all.
+		new chai.Assertion( obj ).to.respondTo( 'getAttribute', message );
+
+		const attributeValue = obj.getAttribute( key );
+		this.assert(
+			attributeValue === value,
+			`expected #{this} to have attribute '${ key }' of #{exp}, but got #{act}`,
+			`expected #{this} to not have attribute '${ key }' of #{exp}`,
+			attributeValue,
+			value
+		);
+	}
+} );

+ 6 - 2
packages/ckeditor5-image/docs/features/image.md

@@ -259,7 +259,11 @@ ClassicEditor
 
 ## Linking images
 
-The {@link module:link/linkimage~LinkImage} plugin adds support for linking images:
+The {@link module:link/linkimage~LinkImage} plugin adds support for linking images. Some use cases where this is needed are:
+
+* Linking to a high-resolution version of an image.
+* Using images as thumbnails linking to an article or product page.
+* Creating banners linking to other pages.
 
 ```html
 <figure class="image">
@@ -284,7 +288,7 @@ The image linking feature is not enabled by default in any of the editor builds.
 
 To add image features to your rich-text editor, install the [`@ckeditor/ckeditor5-image`](https://www.npmjs.com/package/@ckeditor/ckeditor5-image) package:
 
-```bash
+```plaintext
 npm install --save @ckeditor/ckeditor5-image @ckeditor/ckeditor5-link
 ```
 

+ 6 - 2
packages/ckeditor5-link/docs/api/link.md

@@ -8,13 +8,17 @@ category: api-reference
 
 This package implements the link feature for CKEditor 5. It allows for inserting hyperlinks into the edited content and offers the UI to create and edit them.
 
+## Demo
+
+Check out the demo in the {@link features/link Link feature} guide.
+
 ## Documentation
 
-See the {@link module:link/link~Link} plugin documentation.
+See the {@link features/link Link feature} guide and the {@link module:link/link~Link} plugin documentation.
 
 ## Installation
 
-```bash
+```plaintext
 npm install --save @ckeditor/ckeditor5-link
 ```
 

+ 7 - 5
packages/ckeditor5-link/docs/features/link.md

@@ -147,11 +147,13 @@ ClassicEditor
 	.catch( ... );
 ```
 
-#### Adding default link protocol for the external links
+#### Adding default link protocol to external links
 
-Default link protocol can be usefull when user forget to type a full URL address to an external source, site etc. Sometimes copying the text, like for example `ckeditor.com` and converting it to a link may cause some issues. When you do this, the created link will direct you to `yourdomain.com/ckeditor.com`, because you forgot to pass the right protocol which makes the link relative to the site where it appears.
+A default link protocol can be useful when the user forgets to type the full URL address to an external source or website. Sometimes copying the text, like for example `ckeditor.com`, and converting it to a link may cause some issues. As a result, the created link will direct you to `yourdomain.com/ckeditor.com` because of the missing protocol. This makes the link relative to the site where it appears.
 
-Enabling the `{@link module:link/link~LinkConfig#defaultProtocol config.link.defaultProtocol}`, the {@link module:link/link~Link} feature will handle this issue for you. By default it doesn't fix the passed link value, but when you set `{@link module:link/link~LinkConfig#defaultProtocol config.link.defaultProtocol}` to — for example — `http://`, the plugin will add the given protocol to the every link that may need it (like `ckeditor.com`, `example.com` etc. where `[protocol://]example.com` is missing). Here's the basic configuration example:
+After you enable the {@link module:link/link~LinkConfig#defaultProtocol `config.link.defaultProtocol`} configuration option, the link feature will be able to handle this issue for you. By default it does not fix the passed link value, but when you set {@link module:link/link~LinkConfig#defaultProtocol `config.link.defaultProtocol`} to, for example, `http://`, the plugin will add the given protocol to every link that may need it (like `ckeditor.com`, `example.com`, etc. where `[protocol://]example.com` is missing).
+
+See a basic configuration example:
 
 ```js
 ClassicEditor
@@ -166,9 +168,9 @@ ClassicEditor
 ```
 
 <info-box>
-	Having `config.link.defaultProtocol` enabled you are still able to link things locally using `#` or `/`. Protocol won't be added to those links.
+	With the `config.link.defaultProtocol` option enabled, you are still able to link things locally using `#` or `/`. The protocol will not be added to these links.
 
-	Enabled feature also gives you an **email addresses auto-detection** feature. When you submit `hello@example.com`, the plugin will change it automatically to `mailto:hello@example.com`.
+	When enabled, this feature also provides the **email address auto-detection** feature. When you submit `hello@example.com` in your content, the plugin will automatically change it to `mailto:hello@example.com`.
 </info-box>
 
 #### Adding attributes to links based on pre–defined rules (automatic decorators)

+ 4 - 4
packages/ckeditor5-link/src/link.js

@@ -59,10 +59,10 @@ export default class Link extends Plugin {
 
 /**
  * When set, the editor will add the given protocol to the link when the user creates a link without one.
- * For example, when the user is creating a link and types `ckeditor.com` in the link form input — during link submission —
- * the editor will automatically add the `http://` protocol, so the link will be as follows: `http://ckeditor.com`.
+ * For example, when the user is creating a link and types `ckeditor.com` in the link form input, during link submission
+ * the editor will automatically add the `http://` protocol, so the link will look as follows: `http://ckeditor.com`.
  *
- * The feature also comes with an email auto-detection. When you submit `hello@example.com`
+ * The feature also provides email address auto-detection. When you submit `hello@example.com`,
  * the plugin will automatically change it to `mailto:hello@example.com`.
  *
  * 		ClassicEditor
@@ -74,7 +74,7 @@ export default class Link extends Plugin {
  *			.then( ... )
  *			.catch( ... );
  *
- * **NOTE:** In case no configuration is provided, the editor won't auto-fix the links.
+ * **NOTE:** If no configuration is provided, the editor will not auto-fix the links.
  *
  * @member {String} module:link/link~LinkConfig#defaultProtocol
  */

+ 3 - 3
packages/ckeditor5-link/src/linkimageui.js

@@ -20,8 +20,8 @@ import linkIcon from '../theme/icons/link.svg';
 /**
  * The link image UI plugin.
  *
- * This plugin brings a `'linkImage'` button that can be displayed in the {@link module:image/imagetoolbar~ImageToolbar}
- * and used to wrap images in links.
+ * This plugin provides the `'linkImage'` button that can be displayed in the {@link module:image/imagetoolbar~ImageToolbar}.
+ * It can be used to wrap images in links.
  *
  * @extends module:core/plugin~Plugin
  */
@@ -63,7 +63,7 @@ export default class LinkImageUI extends Plugin {
 	 *
 	 * Clicking this button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.
 	 * When an image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or
-	 * {@link module:link/linkui~LinkUI#formView} if it's not.
+	 * {@link module:link/linkui~LinkUI#formView} if it is not.
 	 *
 	 * @private
 	 */

+ 1 - 1
packages/ckeditor5-typing/src/input.js

@@ -47,7 +47,7 @@ export default class Input extends Plugin {
 	 *		const input = editor.plugins.get( 'Input' );
 	 *
 	 *		editor.model.document.on( 'change:data', ( evt, batch ) => {
-	 *			if ( input.isTyping( batch ) ) {
+	 *			if ( input.isInput( batch ) ) {
 	 *				console.log( 'The user typed something...' );
 	 *			}
 	 *		} );

+ 13 - 2
scripts/bump-year.js

@@ -28,18 +28,29 @@ const includeDotFiles = {
 	dot: true
 };
 
-glob( '!(build|coverage|node_modules|packages)/**', updateYear );
+glob( '!(build|coverage|node_modules|external)/**', updateYear );
 
 // LICENSE.md, .eslintrc.js, etc.
 glob( '*', includeDotFiles, updateYear );
 
 function updateYear( err, fileNames ) {
 	const filteredFileNames = fileNames.filter( fileName => {
-		// Filter out stuff from ckeditor5-utils/src/lib.
+		// Filter out nested `node_modules`.
+		if ( minimatch( fileName, '**/node_modules/**' ) ) {
+			return false;
+		}
+
+		// Filter out stuff from `src/lib/`.
 		if ( minimatch( fileName, '**/src/lib/**' ) ) {
 			return false;
 		}
 
+		// Filter out builds.
+		if ( minimatch( fileName, '**/ckeditor5-build-*/build/**' ) ) {
+			return false;
+		}
+
+		// Filter out directories.
 		if ( fs.statSync( fileName ).isDirectory() ) {
 			return false;
 		}