Browse Source

Improved tests in treeView.Matcher.

Szymon Kupś 9 years ago
parent
commit
d95baccfdc

+ 66 - 29
packages/ckeditor5-engine/src/treeview/matcher.js

@@ -47,12 +47,13 @@ export default class Matcher {
 	match( ...elements ) {
 		for ( let element of elements ) {
 			for ( let pattern of this._patterns ) {
-				let isMath = isElementMatching( element, pattern );
+				const match = isElementMatching( element, pattern );
 
-				if ( isMath ) {
+				if ( match ) {
 					return {
 						element: element,
-						pattern: pattern
+						pattern: pattern,
+						match: match
 					};
 				}
 			}
@@ -63,32 +64,50 @@ export default class Matcher {
 }
 
 function isElementMatching( element, pattern ) {
+	const match = {};
+
 	// If pattern is provided as function - return result of that function;
 	if ( typeof pattern == 'function' ) {
 		return pattern( element );
 	}
 
 	// Check element's name.
-	if ( pattern.name && !matchName( pattern.name, element.name ) ) {
-		return false;
+	if ( pattern.name ) {
+		match.name = matchName( pattern.name, element.name );
+
+		if ( !match.name ) {
+			return null;
+		}
 	}
 
 	// Check element's attributes.
-	if ( pattern.attribute && !matchAttributes( pattern.attribute, element ) ) {
-		return false;
+	if ( pattern.attribute ) {
+		match.attribute = matchAttributes( pattern.attribute, element );
+
+		if ( !match.attribute ) {
+			return null;
+		}
 	}
 
 	// Check element's classes.
-	if ( pattern.class && !matchClasses( pattern.class, element ) ) {
-		return false;
+	if ( pattern.class ) {
+		match.class = matchClasses( pattern.class, element );
+
+		if ( !match.class ) {
+			return false;
+		}
 	}
 
 	// Check element's styles.
-	if ( pattern.style && !matchStyles( pattern.style, element ) ) {
-		return false;
+	if ( pattern.style ) {
+		match.style = matchStyles( pattern.style, element );
+
+		if ( !match.style ) {
+			return false;
+		}
 	}
 
-	return true;
+	return match;
 }
 
 function matchName( pattern, name ) {
@@ -101,6 +120,8 @@ function matchName( pattern, name ) {
 }
 
 function matchAttributes( patterns, element ) {
+	const match = [];
+
 	for ( let name in patterns ) {
 		const pattern = patterns[ name ];
 
@@ -108,21 +129,27 @@ function matchAttributes( patterns, element ) {
 			const attribute = element.getAttribute( name );
 
 			if ( pattern instanceof RegExp ) {
-				if ( !pattern.test( attribute ) ) {
-					return false;
+				if ( pattern.test( attribute ) ) {
+					match.push( name );
+				} else {
+					return null;
 				}
-			} else if ( attribute !== pattern  ) {
-				return false;
+			} else if ( attribute === pattern  ) {
+				match.push( name );
+			} else {
+				return null;
 			}
 		} else {
-			return false;
+			return null;
 		}
 	}
 
-	return true;
+	return match;
 }
 
 function matchClasses( patterns, element ) {
+	const match = [];
+
 	for ( let name in patterns ) {
 		const pattern = patterns[ name ];
 
@@ -131,20 +158,26 @@ function matchClasses( patterns, element ) {
 
 			for ( let name of classes ) {
 				if ( pattern.test( name ) ) {
-					return true;
+					match.push( name );
 				}
 			}
 
-			return false;
-		} else if ( !element.hasClass( pattern ) ) {
-			return false;
+			if ( match.length === 0 ) {
+				return null;
+			}
+		} else if ( element.hasClass( pattern ) ) {
+			match.push( pattern );
+		} else {
+			return null;
 		}
 	}
 
-	return true;
+	return match;
 }
 
 function matchStyles( patterns, element ) {
+	const match = [];
+
 	for ( let name in patterns ) {
 		const pattern = patterns[ name ];
 
@@ -152,16 +185,20 @@ function matchStyles( patterns, element ) {
 			const style = element.getStyle( name );
 
 			if ( pattern instanceof RegExp ) {
-				if ( !pattern.test( style ) ) {
-					return false;
+				if ( pattern.test( style ) ) {
+					match.push( name );
+				} else {
+					return null;
 				}
-			} else if ( style !== pattern  ) {
-				return false;
+			} else if ( style === pattern  ) {
+				match.push( name );
+			} else {
+				return null;
 			}
 		} else {
-			return false;
+			return null;
 		}
 	}
 
-	return true;
+	return match;
 }

+ 90 - 59
packages/ckeditor5-engine/tests/treeview/matcher.js

@@ -17,122 +17,153 @@ describe( 'Matcher', () => {
 			const el = new Element( 'p' );
 			const el2 = new Element( 'div' );
 
-			const match = matcher.match( el );
-
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el );
+			const result = matcher.match( el );
+
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).and.equal( el );
+			expect( result ).to.have.property( 'pattern' );
+			expect( result.pattern.name ).to.equal( 'p' );
+			expect( result ).to.have.property( 'match' );
+			expect( result.match.name ).to.be.true;
 			expect( matcher.match( el2 ) ).to.be.null;
 		} );
 
 		it( 'should match element name with RegExp', () => {
-			const matcher = new Matcher( { name: /^text...a$/ } );
+			const pattern = { name: /^text...a$/ };
+			const matcher = new Matcher( pattern );
 			const el1 = new Element( 'textarea' );
 			const el2 = new Element( 'div' );
 
-			const match = matcher.match( el1 );
+			const result = matcher.match( el1 );
 
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el1 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el1 );
+			expect( result ).to.have.property( 'pattern' ).that.has.property( 'name' ).that.equal( pattern.name );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'name' ).that.is.true;
 			expect( matcher.match( el2 ) ).to.be.null;
 		} );
 
 		it( 'should match element attributes', () => {
-			const matcher = new Matcher( {
+			const pattern = {
 				attribute: {
 					title: 'foobar'
 				}
-			} );
+			};
+			const matcher = new Matcher( pattern );
 			const el1 = new Element( 'p', { title: 'foobar'	} );
 			const el2 = new Element( 'p', { title: 'foobaz'	} );
 
-			const match = matcher.match( el1 );
+			const result = matcher.match( el1 );
+
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).and.equal( el1 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+
+			expect( result ).to.have.property( 'match' ).that.has.property( 'attribute' ).that.is.an( 'array' );
 
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el1 );
+			expect( result.match.attribute[ 0 ] ).equal( 'title' );
 			expect( matcher.match( el2 ) ).to.be.null;
 		} );
 
 		it( 'should match element attributes using RegExp', () => {
-			const matcher = new Matcher( {
+			const pattern =  {
 				attribute: {
 					title: /fooba./
 				}
-			} );
+			};
+			const matcher = new Matcher( pattern );
 			const el1 = new Element( 'p', { title: 'foobar'	} );
 			const el2 = new Element( 'p', { title: 'foobaz'	} );
 
-			let match = matcher.match( el1 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el1 );
-
-			match = matcher.match( el2 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el2 );
+			let result = matcher.match( el1 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el1 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'attribute' ).that.is.an( 'array' );
+			expect( result.match.attribute[ 0 ] ).equal( 'title' );
+
+			result = matcher.match( el2 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el2 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'attribute' ).that.is.an( 'array' );
+			expect( result.match.attribute[ 0 ] ).equal( 'title' );
 		} );
 
 		it( 'should match element class names', () => {
-			const matcher = new Matcher( { class: 'foobar' } );
+			const pattern = { class: 'foobar' };
+			const matcher = new Matcher( pattern );
 			const el1 = new Element( 'p', { class: 'foobar' } );
 
-			const match = matcher.match( el1 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el1 );
+			const result = matcher.match( el1 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el1 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'class' ).that.is.an( 'array' );
+			expect( result.match.class[ 0 ] ).equal( 'foobar' );
 		} );
 
 		it( 'should match element class names using RegExp', () => {
-			const matcher = new Matcher( { class: /fooba./ } );
+			const pattern = { class: /fooba./ };
+			const matcher = new Matcher( pattern );
 			const el1 = new Element( 'p', { class: 'foobar'	} );
 			const el2 = new Element( 'p', { class: 'foobaz'	} );
 
-			let match = matcher.match( el1 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el1 );
-
-			match = matcher.match( el2 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el2 );
+			let result = matcher.match( el1 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el1 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'class' ).that.is.an( 'array' );
+			expect( result.match.class[ 0 ] ).equal( 'foobar' );
+
+			result = matcher.match( el2 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el2 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'class' ).that.is.an( 'array' );
+			expect( result.match.class[ 0 ] ).equal( 'foobaz' );
 		} );
 
 		it( 'should match element styles', () => {
-			const matcher = new Matcher( {
+			const pattern = {
 				style: {
 					color: 'red'
 				}
-			} );
+			};
+			const matcher = new Matcher( pattern );
 			const el1 = new Element( 'p', { style: 'color: red' } );
 
-			const match = matcher.match( el1 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el1 );
+			const result = matcher.match( el1 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el1 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'style' ).that.is.an( 'array' );
+			expect( result.match.style[ 0 ] ).equal( 'color' );
 		} );
 
 		it( 'should match element styles using RegExp', () => {
-			const matcher = new Matcher( {
+			const pattern =  {
 				style: {
 					color: /^.*blue$/
 				}
-			} );
+			};
+			const matcher = new Matcher( pattern );
 			const el1 = new Element( 'p', { style: 'color: blue' } );
 			const el2 = new Element( 'p', { style: 'color: darkblue' } );
 
-			let match = matcher.match( el1 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el1 );
-
-			match = matcher.match( el2 );
-			expect( match ).to.be.an( 'object' );
-			expect( match ).to.have.property( 'element' );
-			expect( match.element ).to.equal( el2 );
+			let result = matcher.match( el1 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el1 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'style' ).that.is.an( 'array' );
+			expect( result.match.style[ 0 ] ).to.equal( 'color' );
+
+			result = matcher.match( el2 );
+			expect( result ).to.be.an( 'object' );
+			expect( result ).to.have.property( 'element' ).that.equal( el2 );
+			expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
+			expect( result ).to.have.property( 'match' ).that.has.property( 'style' ).that.is.an( 'array' );
+			expect( result.match.style[ 0 ] ).to.equal( 'color' );
 		} );
 	} );
 } );