| // Copyright 2007 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| goog.provide('goog.dom.patternTest'); |
| goog.setTestOnly('goog.dom.patternTest'); |
| |
| goog.require('goog.dom'); |
| goog.require('goog.dom.NodeType'); |
| goog.require('goog.dom.TagWalkType'); |
| goog.require('goog.dom.pattern.AllChildren'); |
| goog.require('goog.dom.pattern.ChildMatches'); |
| goog.require('goog.dom.pattern.EndTag'); |
| goog.require('goog.dom.pattern.FullTag'); |
| goog.require('goog.dom.pattern.MatchType'); |
| goog.require('goog.dom.pattern.NodeType'); |
| goog.require('goog.dom.pattern.Repeat'); |
| goog.require('goog.dom.pattern.Sequence'); |
| goog.require('goog.dom.pattern.StartTag'); |
| goog.require('goog.dom.pattern.Text'); |
| goog.require('goog.testing.jsunit'); |
| |
| // TODO(robbyw): write a test that checks if backtracking works in Sequence |
| |
| function testStartTag() { |
| var pattern = new goog.dom.pattern.StartTag('DIV'); |
| assertEquals( |
| 'StartTag(div) should match div', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'StartTag(div) should not match span', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'StartTag(div) should not match /div', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| } |
| |
| function testStartTagCase() { |
| var pattern = new goog.dom.pattern.StartTag('diV'); |
| assertEquals( |
| 'StartTag(diV) should match div', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'StartTag(diV) should not match span', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| } |
| |
| function testStartTagRegex() { |
| var pattern = new goog.dom.pattern.StartTag(/D/); |
| assertEquals( |
| 'StartTag(/D/) should match div', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'StartTag(/D/) should not match span', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'StartTag(/D/) should not match /div', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| } |
| |
| function testStartTagAttributes() { |
| var pattern = new goog.dom.pattern.StartTag('DIV', {id: 'div1'}); |
| assertEquals( |
| 'StartTag(div,id:div1) should match div1', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals('StartTag(div,id:div2) should not match div1', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div2'), |
| goog.dom.TagWalkType.START_TAG)); |
| } |
| |
| function testStartTagStyle() { |
| var pattern = new goog.dom.pattern.StartTag('SPAN', null, {color: 'red'}); |
| assertEquals( |
| 'StartTag(span,null,color:red) should match span1', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'StartTag(span,null,color:blue) should not match span1', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span2'), |
| goog.dom.TagWalkType.START_TAG)); |
| } |
| |
| function testStartTagAttributeRegex() { |
| var pattern = new goog.dom.pattern.StartTag('SPAN', {id: /span\d/}); |
| assertEquals( |
| 'StartTag(span,id:/span\\d/) should match span1', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'StartTag(span,id:/span\\d/) should match span2', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| } |
| |
| function testEndTag() { |
| var pattern = new goog.dom.pattern.EndTag('DIV'); |
| assertEquals( |
| 'EndTag should match div', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| } |
| |
| function testEndTagRegex() { |
| var pattern = new goog.dom.pattern.EndTag(/D/); |
| assertEquals( |
| 'EndTag(/D/) should match /div', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'EndTag(/D/) should not match /span', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'EndTag(/D/) should not match div', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| } |
| |
| function testChildMatches() { |
| var pattern = new goog.dom.pattern.ChildMatches( |
| new goog.dom.pattern.StartTag('DIV'), 2); |
| |
| assertEquals( |
| 'ChildMatches should match div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'ChildMatches should match /div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'ChildMatches should match div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div2'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'ChildMatches should match /div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div2'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'ChildMatches should finish match at /body', |
| goog.dom.pattern.MatchType.BACKTRACK_MATCH, |
| pattern.matchToken( |
| document.body, |
| goog.dom.TagWalkType.END_TAG)); |
| |
| assertEquals( |
| 'ChildMatches should match div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div2'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'ChildMatches should match /div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div2'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'ChildMatches should fail to match at /body: not enough child matches', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| document.body, |
| goog.dom.TagWalkType.END_TAG)); |
| } |
| |
| function testFullTag() { |
| var pattern = new goog.dom.pattern.FullTag('DIV'); |
| assertEquals( |
| 'FullTag(div) should match div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'FullTag(div) should match /div', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| |
| assertEquals( |
| 'FullTag(div) should start match at div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'FullTag(div) should continue to match span', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'FullTag(div) should continue to match /span', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'FullTag(div) should finish match at /div', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| } |
| |
| function testAllChildren() { |
| var pattern = new goog.dom.pattern.AllChildren(); |
| assertEquals( |
| 'AllChildren(div) should match div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'AllChildren(div) should match /div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'AllChildren(div) should match at /body', |
| goog.dom.pattern.MatchType.BACKTRACK_MATCH, |
| pattern.matchToken( |
| document.body, |
| goog.dom.TagWalkType.END_TAG)); |
| |
| assertEquals( |
| 'AllChildren(div) should start match at div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'AllChildren(div) should continue to match span', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'AllChildren(div) should continue to match /span', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'AllChildren(div) should continue to match at /div', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'AllChildren(div) should finish match at /body', |
| goog.dom.pattern.MatchType.BACKTRACK_MATCH, |
| pattern.matchToken( |
| document.body, |
| goog.dom.TagWalkType.END_TAG)); |
| } |
| |
| function testText() { |
| var pattern = new goog.dom.pattern.Text('Text'); |
| assertEquals( |
| 'Text should match div3/text()', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div3').firstChild, |
| goog.dom.TagWalkType.OTHER)); |
| assertEquals( |
| 'Text should not match div4/text()', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div4').firstChild, |
| goog.dom.TagWalkType.OTHER)); |
| assertEquals( |
| 'Text should not match div3', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div3'), |
| goog.dom.TagWalkType.START_TAG)); |
| |
| } |
| |
| function testTextRegex() { |
| var pattern = new goog.dom.pattern.Text(/Text/); |
| assertEquals( |
| 'Text(regex) should match div3/text()', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div3').firstChild, |
| goog.dom.TagWalkType.OTHER)); |
| assertEquals( |
| 'Text(regex) should match div4/text()', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div4').firstChild, |
| goog.dom.TagWalkType.OTHER)); |
| } |
| |
| function testNodeType() { |
| var pattern = new goog.dom.pattern.NodeType(goog.dom.NodeType.COMMENT); |
| assertEquals('Comment matcher should match a comment', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('nodeTypes').firstChild, |
| goog.dom.TagWalkType.OTHER)); |
| assertEquals('Comment matcher should not match a text node', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('nodeTypes').lastChild, |
| goog.dom.TagWalkType.OTHER)); |
| } |
| |
| function testSequence() { |
| var pattern = new goog.dom.pattern.Sequence([ |
| new goog.dom.pattern.StartTag('DIV'), |
| new goog.dom.pattern.StartTag('SPAN'), |
| new goog.dom.pattern.EndTag('SPAN'), |
| new goog.dom.pattern.EndTag('DIV')]); |
| |
| assertEquals( |
| 'Sequence[0] should match div1', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[1] should match span1', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[2] should match /span1', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'Sequence[3] should match /div1', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| |
| assertEquals( |
| 'Sequence[0] should match div1 again', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[1] should match span1 again', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[2] should match /span1 again', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'Sequence[3] should match /div1 again', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| |
| assertEquals( |
| 'Sequence[0] should match div1', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[1] should not match div1', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| |
| assertEquals( |
| 'Sequence[0] should match div1 after failure', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[1] should match span1 after failure', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[2] should match /span1 after failure', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('span1'), |
| goog.dom.TagWalkType.END_TAG)); |
| assertEquals( |
| 'Sequence[3] should match /div1 after failure', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('div1'), |
| goog.dom.TagWalkType.END_TAG)); |
| } |
| |
| function testRepeat() { |
| var pattern = new goog.dom.pattern.Repeat( |
| new goog.dom.pattern.StartTag('B')); |
| |
| // Note: this test does not mimic an actual matcher because it is only |
| // passing the START_TAG events. |
| |
| assertEquals( |
| 'Repeat[B] should match b1', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('b1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Repeat[B] should match b2', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('b2'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Repeat[B] should backtrack match i1', |
| goog.dom.pattern.MatchType.BACKTRACK_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('i1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Repeat[B] should have match count of 2', |
| 2, |
| pattern.count); |
| |
| assertEquals( |
| 'Repeat[B] should backtrack match i1 even with no b matches', |
| goog.dom.pattern.MatchType.BACKTRACK_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('i1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Repeat[B] should have match count of 0', |
| 0, |
| pattern.count); |
| } |
| |
| function testRepeatWithMinimum() { |
| var pattern = new goog.dom.pattern.Repeat( |
| new goog.dom.pattern.StartTag('B'), 1); |
| |
| // Note: this test does not mimic an actual matcher because it is only |
| // passing the START_TAG events. |
| |
| assertEquals( |
| 'Repeat[B,1] should match b1', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('b1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Repeat[B,1] should match b2', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken( |
| goog.dom.getElement('b2'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Repeat[B,1] should backtrack match i1', |
| goog.dom.pattern.MatchType.BACKTRACK_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('i1'), |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Repeat[B,1] should have match count of 2', |
| 2, |
| pattern.count); |
| |
| assertEquals( |
| 'Repeat[B,1] should not match i1', |
| goog.dom.pattern.MatchType.NO_MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('i1'), |
| goog.dom.TagWalkType.START_TAG)); |
| } |
| |
| function testRepeatWithMaximum() { |
| var pattern = new goog.dom.pattern.Repeat( |
| new goog.dom.pattern.StartTag('B'), 1, 1); |
| |
| // Note: this test does not mimic an actual matcher because it is only |
| // passing the START_TAG events. |
| |
| assertEquals( |
| 'Repeat[B,1] should match b1', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken( |
| goog.dom.getElement('b1'), |
| goog.dom.TagWalkType.START_TAG)); |
| } |
| |
| function testSequenceBacktrack() { |
| var pattern = new goog.dom.pattern.Sequence([ |
| new goog.dom.pattern.Repeat(new goog.dom.pattern.StartTag('SPAN')), |
| new goog.dom.pattern.Text('X')]); |
| |
| var root = goog.dom.getElement('span3'); |
| assertEquals( |
| 'Sequence[Repeat[SPAN],"X"] should match span3', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken(root, goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[Repeat[SPAN],"X"] should match span3.firstChild', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken(root.firstChild, |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[Repeat[SPAN],"X"] should match span3.firstChild.firstChild', |
| goog.dom.pattern.MatchType.MATCHING, |
| pattern.matchToken(root.firstChild.firstChild, |
| goog.dom.TagWalkType.START_TAG)); |
| assertEquals( |
| 'Sequence[Repeat[SPAN],"X"] should finish match text node', |
| goog.dom.pattern.MatchType.MATCH, |
| pattern.matchToken(root.firstChild.firstChild.firstChild, |
| goog.dom.TagWalkType.OTHER)); |
| } |