| import 'package:analyzer/src/generated/source.dart'; |
| import 'package:angular_analyzer_plugin/src/model.dart'; |
| import 'package:angular_analyzer_plugin/src/selector.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| import 'package:mockito/mockito.dart'; |
| import 'package:test/test.dart'; |
| |
| // 'typed' is deprecated and shouldn't be used. |
| // ignore_for_file: deprecated_member_use |
| |
| void main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(AndSelectorTest); |
| defineReflectiveTests(AttributeSelectorTest); |
| defineReflectiveTests(AttributeContainsSelectorTest); |
| defineReflectiveTests(ClassSelectorTest); |
| defineReflectiveTests(ElementNameSelectorTest); |
| defineReflectiveTests(OrSelectorTest); |
| defineReflectiveTests(NotSelectorTest); |
| defineReflectiveTests(AttributeValueRegexSelectorTest); |
| defineReflectiveTests(AttributeStartsWithSelectorTest); |
| defineReflectiveTests(SelectorParserTest); |
| defineReflectiveTests(SuggestTagsTest); |
| defineReflectiveTests(HtmlTagForSelectorTest); |
| }); |
| } |
| |
| @reflectiveTest |
| class AndSelectorTest extends _SelectorTest { |
| final selector1 = new _SelectorMock('aaa'); |
| final selector2 = new _SelectorMock('bbb'); |
| final selector3 = new _SelectorMock('ccc'); |
| |
| AndSelector selector; |
| |
| @override |
| void setUp() { |
| super.setUp(); |
| selector = new AndSelector(<Selector>[selector1, selector2, selector3]); |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NonTagMatch); |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NonTagMatch); |
| when(selector3.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NonTagMatch); |
| |
| when(selector1.availableTo(typed(any))).thenReturn(true); |
| when(selector2.availableTo(typed(any))).thenReturn(true); |
| when(selector3.availableTo(typed(any))).thenReturn(true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match() { |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(2); |
| verify(selector2.match(typed(any), typed(any))).called(2); |
| verify(selector3.match(typed(any), typed(any))).called(2); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_false1() { |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NoMatch); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verifyNever(selector2.match(typed(any), typed(any))); |
| verifyNever(selector3.match(typed(any), typed(any))); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_false2() { |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NoMatch); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verify(selector2.match(typed(any), typed(any))).called(1); |
| verifyNever(selector3.match(typed(any), typed(any))); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_falseTagMatch() { |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.TagMatch); |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NoMatch); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verify(selector2.match(typed(any), typed(any))).called(1); |
| verifyNever(selector3.match(typed(any), typed(any))); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_TagMatch1() { |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.TagMatch); |
| expect(selector.match(element, template), equals(SelectorMatch.TagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(2); |
| verify(selector2.match(typed(any), typed(any))).called(2); |
| verify(selector3.match(typed(any), typed(any))).called(2); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_TagMatch2() { |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.TagMatch); |
| expect(selector.match(element, template), equals(SelectorMatch.TagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(2); |
| verify(selector2.match(typed(any), typed(any))).called(2); |
| verify(selector3.match(typed(any), typed(any))).called(2); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_availableTo_allMatch() { |
| expect(selector.availableTo(element), true); |
| verify(selector1.availableTo(typed(any))).called(1); |
| verify(selector2.availableTo(typed(any))).called(1); |
| verify(selector3.availableTo(typed(any))).called(1); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_availableTo_singleUnmatch() { |
| when(selector2.availableTo(typed(any))).thenReturn(false); |
| expect(selector.availableTo(element), equals(false)); |
| verify(selector1.availableTo(typed(any))).called(1); |
| verify(selector2.availableTo(typed(any))).called(1); |
| verifyNever(selector3.availableTo(typed(any))); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toString() { |
| expect(selector.toString(), 'aaa && bbb && ccc'); |
| } |
| } |
| |
| @reflectiveTest |
| class AttributeSelectorTest extends _SelectorTest { |
| final AngularElement nameElement = |
| new AngularElementImpl('kind', 10, 5, null); |
| |
| // ignore: non_constant_identifier_names |
| void test_match_notName() { |
| final selector = new AttributeSelector(nameElement, null); |
| when(element.attributes).thenReturn({'not-kind': 'no-matter'}); |
| when(element.attributeNameSpans).thenReturn({'not-kind': null}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_notValue() { |
| final selector = new AttributeSelector(nameElement, 'silly'); |
| when(element.attributes).thenReturn({'kind': 'strange'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, "kind")}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_name_value() { |
| final selector = new AttributeSelector(nameElement, 'silly'); |
| when(element.attributes).thenReturn({'kind': 'silly'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, 'kind')}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| _assertRange(resolvedRanges[0], 100, 4, selector.nameElement); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_noValue() { |
| final selector = new AttributeSelector(nameElement, null); |
| when(element.attributes).thenReturn({'kind': 'no-matter'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, "kind")}); |
| // verify |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| _assertRange(resolvedRanges[0], 100, 4, selector.nameElement); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toString_hasValue() { |
| final selector = new AttributeSelector(nameElement, 'daffy'); |
| expect(selector.toString(), '[kind=daffy]'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toString_noValue() { |
| final selector = new AttributeSelector(nameElement, null); |
| expect(selector.toString(), '[kind]'); |
| } |
| } |
| |
| @reflectiveTest |
| class AttributeContainsSelectorTest extends _SelectorTest { |
| final AngularElement nameElement = |
| new AngularElementImpl('kind', 10, 5, null); |
| // ignore: non_constant_identifier_names |
| void test_match() { |
| final selector = new AttributeContainsSelector(nameElement, 'search'); |
| when(element.attributes).thenReturn({'kind': 'include the search here'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, 'kind')}); |
| // verify |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| _assertRange(resolvedRanges[0], 100, 4, selector.nameElement); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_begins() { |
| final selector = new AttributeContainsSelector(nameElement, 'start'); |
| when(element.attributes).thenReturn({'kind': 'start is matched'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, 'kind')}); |
| // verify |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| _assertRange(resolvedRanges[0], 100, 4, selector.nameElement); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_ends() { |
| final selector = new AttributeContainsSelector(nameElement, 'end'); |
| when(element.attributes).thenReturn({'kind': 'matches at the end'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, 'kind')}); |
| // verify |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| _assertRange(resolvedRanges[0], 100, 4, selector.nameElement); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_noMatch_value() { |
| final selector = |
| new AttributeContainsSelector(nameElement, 'not appearing'); |
| when(element.attributes).thenReturn({'kind': 'not related'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, 'kind')}); |
| // verify |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), false); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_noMatch_attributeName() { |
| final selector = new AttributeContainsSelector(nameElement, 'match'); |
| when(element.attributes).thenReturn({'unmatched': 'this is matched'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'unmatched': _newStringSpan(100, 'unmatched')}); |
| // verify |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| } |
| |
| @reflectiveTest |
| class ClassSelectorTest extends _SelectorTest { |
| final nameElement = new AngularElementImpl('nice', 10, 5, null); |
| ClassSelector selector; |
| |
| @override |
| void setUp() { |
| super.setUp(); |
| selector = new ClassSelector(nameElement); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_false_noClass() { |
| when(element.attributes).thenReturn({'not-class': 'no-matter'}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_false_noSuchClass() { |
| when(element.attributes).thenReturn({'class': 'not-nice'}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_true_first() { |
| final classValue = 'nice some other'; |
| when(element.attributes).thenReturn({'class': classValue}); |
| when(element.attributeValueSpans) |
| .thenReturn({'class': _newStringSpan(100, classValue)}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| expect(resolvedRanges, hasLength(1)); |
| _assertRange(resolvedRanges[0], 100, 4, selector.nameElement); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_true_last() { |
| final classValue = 'some other nice'; |
| when(element.attributes).thenReturn({'class': classValue}); |
| when(element.attributeValueSpans) |
| .thenReturn({'class': _newStringSpan(100, classValue)}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| expect(resolvedRanges, hasLength(1)); |
| _assertRange(resolvedRanges[0], 111, 4, selector.nameElement); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_true_middle() { |
| final classValue = 'some nice other'; |
| when(element.attributes).thenReturn({'class': classValue}); |
| when(element.attributeValueSpans) |
| .thenReturn({'class': _newStringSpan(100, classValue)}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| expect(resolvedRanges, hasLength(1)); |
| _assertRange(resolvedRanges[0], 105, 4, selector.nameElement); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toString() { |
| expect(selector.toString(), '.nice'); |
| } |
| } |
| |
| @reflectiveTest |
| class ElementNameSelectorTest extends _SelectorTest { |
| ElementNameSelector selector; |
| |
| @override |
| void setUp() { |
| super.setUp(); |
| selector = |
| new ElementNameSelector(new AngularElementImpl('panel', 10, 5, null)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match() { |
| when(element.localName).thenReturn('panel'); |
| when(element.openingNameSpan).thenReturn(_newStringSpan(100, 'panel')); |
| when(element.closingNameSpan).thenReturn(_newStringSpan(200, 'panel')); |
| expect(selector.match(element, template), equals(SelectorMatch.TagMatch)); |
| expect(selector.availableTo(element), true); |
| _assertRange(resolvedRanges[0], 100, 5, selector.nameElement); |
| _assertRange(resolvedRanges[1], 200, 5, selector.nameElement); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_not() { |
| when(element.localName).thenReturn('not-panel'); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toString() { |
| expect(selector.toString(), 'panel'); |
| } |
| } |
| |
| @reflectiveTest |
| class AttributeValueRegexSelectorTest extends _SelectorTest { |
| final selector = new AttributeValueRegexSelector("abc"); |
| |
| // ignore: non_constant_identifier_names |
| void test_noMatch() { |
| when(element.attributes).thenReturn({'kind': 'bcd'}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_noMatch_any() { |
| when(element.attributes) |
| .thenReturn({'kind': 'bcd', 'plop': 'cde', 'klark': 'efg'}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match() { |
| when(element.attributes).thenReturn({'kind': '0abcd'}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_justOne() { |
| when(element.attributes) |
| .thenReturn({'kind': 'bcd', 'plop': 'zabcz', 'klark': 'efg'}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| } |
| |
| @reflectiveTest |
| class AttributeStartsWithSelectorTest extends _SelectorTest { |
| final selector = new AttributeStartsWithSelector( |
| new AngularElementImpl('abc', 10, 5, null), 'xyz'); |
| |
| // ignore: non_constant_identifier_names |
| void test_noMatch_wrongAttrName() { |
| when(element.attributes).thenReturn({'abcd': 'xyz'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'abcd': _newStringSpan(100, 'abcd')}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(true)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_noMatch_valueNotStartWith() { |
| when(element.attributes).thenReturn({'abc': 'axyz'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'abc': _newStringSpan(100, 'abc')}); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| // available to is false, because the attribute already exists and so |
| // suggesting it would lead to duplication. |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_noMatch_any() { |
| when(element.attributes).thenReturn( |
| {'abc': 'wrong value', 'wrong-attr': 'xyz', 'klark': 'efg'}); |
| when(element.attributeNameSpans).thenReturn({ |
| 'abc': _newStringSpan(100, 'abc'), |
| 'xyz': _newStringSpan(110, 'xyz'), |
| 'klark': _newStringSpan(120, 'klark') |
| }); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_exactMatch() { |
| when(element.attributes).thenReturn({'abc': 'xyz'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'abc': _newStringSpan(100, 'abc')}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_withExtraCharsMatch() { |
| when(element.attributes).thenReturn({'abc': 'xyz and stuff'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'abc': _newStringSpan(100, 'abc')}); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_justOne() { |
| when(element.attributes) |
| .thenReturn({'abc': 'xyz and stuff', 'plop': 'zabcz', 'klark': 'efg'}); |
| when(element.attributeNameSpans).thenReturn({ |
| 'abc': _newStringSpan(100, 'abc'), |
| 'plop': _newStringSpan(110, 'plop'), |
| 'klark': _newStringSpan(120, 'klark') |
| }); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| } |
| |
| @reflectiveTest |
| class NotSelectorTest extends _SelectorTest { |
| final condition = new _SelectorMock('aaa'); |
| |
| NotSelector selector; |
| |
| @override |
| void setUp() { |
| super.setUp(); |
| selector = new NotSelector(condition); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_notFalse() { |
| when(condition.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NoMatch); |
| when(condition.availableTo(typed(any))).thenReturn(false); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_notTagMatch() { |
| when(condition.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.TagMatch); |
| when(condition.availableTo(typed(any))).thenReturn(true); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_notNonTagMatch() { |
| when(condition.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NonTagMatch); |
| when(condition.availableTo(typed(any))).thenReturn(true); |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_notAttribute_availableTo_true() { |
| final nameElement = new AngularElementImpl('kind', 10, 5, null); |
| final attributeSelector = new AttributeSelector(nameElement, null); |
| when(element.attributes).thenReturn({'not-kind': 'strange'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'not-kind': _newStringSpan(100, 'not-kind')}); |
| selector = new NotSelector(attributeSelector); |
| expect(selector.availableTo(element), true); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_notAttribute_availableTo_false() { |
| final nameElement = new AngularElementImpl('kind', 10, 5, null); |
| final attributeSelector = new AttributeSelector(nameElement, null); |
| when(element.attributes).thenReturn({'kind': 'strange'}); |
| when(element.attributeNameSpans) |
| .thenReturn({'kind': _newStringSpan(100, 'kind')}); |
| selector = new NotSelector(attributeSelector); |
| expect(selector.availableTo(element), equals(false)); |
| } |
| } |
| |
| @reflectiveTest |
| class OrSelectorTest extends _SelectorTest { |
| final selector1 = new _SelectorMock('aaa'); |
| final selector2 = new _SelectorMock('bbb'); |
| final selector3 = new _SelectorMock('ccc'); |
| |
| OrSelector selector; |
| |
| @override |
| void setUp() { |
| super.setUp(); |
| selector = new OrSelector(<Selector>[selector1, selector2, selector3]); |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NoMatch); |
| when(selector1.availableTo(typed(any))).thenReturn(false); |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NoMatch); |
| when(selector2.availableTo(typed(any))).thenReturn(false); |
| when(selector3.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NoMatch); |
| when(selector3.availableTo(typed(any))).thenReturn(false); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_matchFirstIsTagMatch() { |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.TagMatch); |
| when(selector1.availableTo(typed(any))).thenReturn(true); |
| expect(selector.match(element, template), equals(SelectorMatch.TagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verifyNever(selector2.match(typed(any), typed(any))); |
| verifyNever(selector3.match(typed(any), typed(any))); |
| |
| expect(selector.availableTo(element), true); |
| verify(selector1.availableTo(typed(any))).called(1); |
| verifyNever(selector2.availableTo(typed(any))); |
| verifyNever(selector3.availableTo(typed(any))); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_matchFirstIsNonTagMatch() { |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NonTagMatch); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verify(selector2.match(typed(any), typed(any))).called(1); |
| verify(selector3.match(typed(any), typed(any))).called(1); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match2TagMatch() { |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.TagMatch); |
| when(selector2.availableTo(typed(any))).thenReturn(true); |
| expect(selector.match(element, template), equals(SelectorMatch.TagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verify(selector2.match(typed(any), typed(any))).called(1); |
| verifyNever(selector3.match(typed(any), typed(any))); |
| |
| expect(selector.availableTo(element), true); |
| verify(selector1.availableTo(typed(any))).called(1); |
| verify(selector2.availableTo(typed(any))).called(1); |
| verifyNever(selector3.availableTo(typed(any))); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match2NonTagMatch() { |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NonTagMatch); |
| expect( |
| selector.match(element, template), equals(SelectorMatch.NonTagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verify(selector2.match(typed(any), typed(any))).called(1); |
| verify(selector3.match(typed(any), typed(any))).called(1); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match2TagAndNonTagMatch() { |
| when(selector1.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.NonTagMatch); |
| when(selector2.match(typed(any), typed(any))) |
| .thenReturn(SelectorMatch.TagMatch); |
| expect(selector.match(element, template), equals(SelectorMatch.TagMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verify(selector2.match(typed(any), typed(any))).called(1); |
| verifyNever(selector3.match(typed(any), typed(any))); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_match_false() { |
| expect(selector.match(element, template), equals(SelectorMatch.NoMatch)); |
| verify(selector1.match(typed(any), typed(any))).called(1); |
| verify(selector2.match(typed(any), typed(any))).called(1); |
| verify(selector3.match(typed(any), typed(any))).called(1); |
| |
| expect(selector.availableTo(element), equals(false)); |
| verify(selector1.availableTo(typed(any))).called(1); |
| verify(selector2.availableTo(typed(any))).called(1); |
| verify(selector3.availableTo(typed(any))).called(1); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toString() { |
| expect(selector.toString(), 'aaa || bbb || ccc'); |
| } |
| } |
| |
| @reflectiveTest |
| class SelectorParserTest { |
| final Source source = new _SourceMock(); |
| |
| // ignore: non_constant_identifier_names |
| void test_and() { |
| final AndSelector selector = |
| new SelectorParser(source, 10, '[ng-for][ng-for-of]').parse(); |
| expect(selector.selectors, hasLength(2)); |
| { |
| final AttributeSelector subSelector = selector.selectors[0]; |
| final nameElement = subSelector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'ng-for'); |
| expect(nameElement.nameOffset, 11); |
| expect(nameElement.nameLength, 'ng-for'.length); |
| } |
| { |
| final AttributeSelector subSelector = selector.selectors[1]; |
| final nameElement = subSelector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'ng-for-of'); |
| expect(nameElement.nameOffset, 19); |
| expect(nameElement.nameLength, 'ng-for-of'.length); |
| } |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_hasValue() { |
| final AttributeSelector selector = |
| new SelectorParser(source, 10, '[kind=pretty]').parse(); |
| { |
| final nameElement = selector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'kind'); |
| expect(nameElement.nameOffset, 11); |
| expect(nameElement.nameLength, 'kind'.length); |
| } |
| expect(selector.value, 'pretty'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_hasValueWithQuotes() { |
| final AndSelector selector = |
| new SelectorParser(source, 10, '''[single='quotes'][double="quotes"]''') |
| .parse(); |
| expect(selector.selectors, hasLength(2)); |
| { |
| final AttributeSelector subSelector = selector.selectors[0]; |
| { |
| final nameElement = subSelector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'single'); |
| } |
| // Ensure there are no quotes within the value |
| expect(subSelector.value, 'quotes'); |
| } |
| { |
| final AttributeSelector subSelector = selector.selectors[1]; |
| { |
| final nameElement = subSelector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'double'); |
| } |
| // Ensure there are no quotes within the value |
| expect(subSelector.value, 'quotes'); |
| } |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_hasWildcard() { |
| final AttributeContainsSelector selector = |
| new SelectorParser(source, 10, '[kind*=pretty]').parse(); |
| { |
| final nameElement = selector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'kind'); |
| expect(nameElement.nameOffset, 11); |
| expect(nameElement.nameLength, 'kind'.length); |
| } |
| expect(selector.value, 'pretty'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_textRegex() { |
| final AttributeValueRegexSelector selector = |
| new SelectorParser(source, 10, '[*=/pretty/]').parse(); |
| expect(selector.regexpStr, 'pretty'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_noValue() { |
| final AttributeSelector selector = |
| new SelectorParser(source, 10, '[ng-for]').parse(); |
| { |
| final nameElement = selector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'ng-for'); |
| expect(nameElement.nameOffset, 11); |
| expect(nameElement.nameLength, 'ng-for'.length); |
| } |
| expect(selector.value, isNull); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_startsWith() { |
| final AttributeStartsWithSelector selector = |
| new SelectorParser(source, 10, '[foo^=bar]').parse(); |
| expect(selector.nameElement.name, 'foo'); |
| expect(selector.value, 'bar'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_startsWith_quoted() { |
| final AttributeStartsWithSelector selector = |
| new SelectorParser(source, 10, '[foo^="bar"]').parse(); |
| expect(selector.nameElement.name, 'foo'); |
| expect(selector.value, 'bar'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_regularOperator_noValue() { |
| try { |
| new SelectorParser(source, 0, '[foo=]').parse(); |
| } on FormatException catch (e) { |
| expect(e.message, contains('Expected a value after =, got ]')); |
| expect(e.offset, '[foo='.length); |
| return; |
| } |
| fail("was supposed to throw"); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_beginsWithOperator_noValue() { |
| try { |
| new SelectorParser(source, 0, '[foo^=]').parse(); |
| } on FormatException catch (e) { |
| expect(e.message, contains('Expected a value after ^=, got ]')); |
| expect(e.offset, '[foo^='.length); |
| return; |
| } |
| fail("was supposed to throw"); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_attribute_containsOperator_noValue() { |
| try { |
| new SelectorParser(source, 0, '[foo*=]').parse(); |
| } on FormatException catch (e) { |
| expect(e.message, contains('Expected a value after *=, got ]')); |
| expect(e.offset, '[foo*='.length); |
| return; |
| } |
| fail("was supposed to throw"); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_bad() { |
| try { |
| new SelectorParser(source, 0, '+name').parse(); |
| } catch (e) { |
| return; |
| } |
| fail("was supposed to throw"); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_class() { |
| final ClassSelector selector = |
| new SelectorParser(source, 10, '.nice').parse(); |
| final nameElement = selector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'nice'); |
| expect(nameElement.nameOffset, 11); |
| expect(nameElement.nameLength, 'nice'.length); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_elementName() { |
| final ElementNameSelector selector = |
| new SelectorParser(source, 10, 'text-panel').parse(); |
| final nameElement = selector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'text-panel'); |
| expect(nameElement.nameOffset, 10); |
| expect(nameElement.nameLength, 'text-panel'.length); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_or() { |
| final OrSelector selector = |
| new SelectorParser(source, 10, 'aaa,bbb').parse(); |
| expect(selector.selectors, hasLength(2)); |
| { |
| final ElementNameSelector subSelector = selector.selectors[0]; |
| final nameElement = subSelector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'aaa'); |
| expect(nameElement.nameOffset, 10); |
| expect(nameElement.nameLength, 'aaa'.length); |
| } |
| { |
| final ElementNameSelector subSelector = selector.selectors[1]; |
| final nameElement = subSelector.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'bbb'); |
| expect(nameElement.nameOffset, 14); |
| expect(nameElement.nameLength, 'bbb'.length); |
| } |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_not() { |
| final NotSelector selector = |
| new SelectorParser(source, 10, ':not(aaa)').parse(); |
| { |
| final ElementNameSelector condition = selector.condition; |
| final nameElement = condition.nameElement; |
| expect(nameElement.source, source); |
| expect(nameElement.name, 'aaa'); |
| expect(nameElement.nameOffset, 15); |
| expect(nameElement.nameLength, 'aaa'.length); |
| } |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_contains() { |
| final ContainsSelector selector = |
| new SelectorParser(source, 10, ':contains(/aaa/)').parse(); |
| expect(selector.regex, 'aaa'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_complex_ast() { |
| final OrSelector selector = new SelectorParser( |
| source, 10, 'aaa, bbb:not(ccc), :not(:not(ddd)[eee], fff[ggg])') |
| .parse(); |
| |
| expect( |
| selector.toString(), |
| equals('aaa || bbb && :not(ccc) || ' |
| ':not(:not(ddd) && [eee] || fff && [ggg])')); |
| { |
| final ElementNameSelector subSelector = selector.selectors[0]; |
| expect(subSelector.toString(), "aaa"); |
| } |
| { |
| final AndSelector subSelector = selector.selectors[1]; |
| expect(subSelector.toString(), "bbb && :not(ccc)"); |
| { |
| final ElementNameSelector subSelector2 = subSelector.selectors[0]; |
| expect(subSelector2.toString(), "bbb"); |
| } |
| { |
| final NotSelector subSelector2 = subSelector.selectors[1]; |
| expect(subSelector2.toString(), ":not(ccc)"); |
| { |
| final ElementNameSelector subSelector3 = subSelector2.condition; |
| expect(subSelector3.toString(), "ccc"); |
| } |
| } |
| } |
| { |
| final NotSelector subSelector = selector.selectors[2]; |
| expect( |
| subSelector.toString(), ":not(:not(ddd) && [eee] || fff && [ggg])"); |
| { |
| final OrSelector subSelector2 = subSelector.condition; |
| expect(subSelector2.toString(), ":not(ddd) && [eee] || fff && [ggg]"); |
| { |
| final AndSelector subSelector3 = subSelector2.selectors[0]; |
| expect(subSelector3.toString(), ":not(ddd) && [eee]"); |
| { |
| final NotSelector subSelector4 = subSelector3.selectors[0]; |
| expect(subSelector4.toString(), ":not(ddd)"); |
| { |
| final ElementNameSelector subSelector5 = subSelector4.condition; |
| expect(subSelector5.toString(), "ddd"); |
| } |
| } |
| { |
| final AttributeSelector subSelector4 = subSelector3.selectors[1]; |
| expect(subSelector4.toString(), "[eee]"); |
| } |
| } |
| { |
| final AndSelector subSelector3 = subSelector2.selectors[1]; |
| expect(subSelector3.toString(), "fff && [ggg]"); |
| { |
| final ElementNameSelector subSelector4 = subSelector3.selectors[0]; |
| expect(subSelector4.toString(), "fff"); |
| } |
| { |
| final AttributeSelector subSelector4 = subSelector3.selectors[1]; |
| expect(subSelector4.toString(), "[ggg]"); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| @reflectiveTest |
| class SuggestTagsTest { |
| // ignore: non_constant_identifier_names |
| void test_suggestNodeName() { |
| final selector = |
| new ElementNameSelector(new AngularElementImpl('panel', 10, 5, null)); |
| |
| final suggestions = selector.suggestTags(); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isTrue); |
| expect(suggestions.first.toString(), equals("<panel")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestTagsFiltersInvalidResults() { |
| final selector = |
| new ClassSelector(new AngularElementImpl('class', 10, 5, null)); |
| expect(_evenInvalidSuggestions(selector), hasLength(1)); |
| expect(_evenInvalidSuggestions(selector).first.isValid, isFalse); |
| expect(selector.suggestTags(), hasLength(0)); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestClass() { |
| final selector = |
| new ClassSelector(new AngularElementImpl('myclass', 10, 5, null)); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isFalse); |
| expect(suggestions.first.toString(), equals('<null class="myclass"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestClasses() { |
| final selector1 = |
| new ClassSelector(new AngularElementImpl('class1', 10, 5, null)); |
| final selector2 = |
| new ClassSelector(new AngularElementImpl('class2', 10, 5, null)); |
| |
| final suggestions = |
| selector2.refineTagSuggestions(_evenInvalidSuggestions(selector1)); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isFalse); |
| // check ClassSelector used tag.addClass(x), not tag.setAttr("class", x) |
| expect(suggestions.first.toString(), equals('<null class="class1 class2"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestPropertyNoValue() { |
| final selector = new AttributeSelector( |
| new AngularElementImpl('attr', 10, 5, null), null); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isFalse); |
| expect(suggestions.first.toString(), equals("<null attr")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestPropertyWithValue() { |
| final selector = new AttributeSelector( |
| new AngularElementImpl('attr', 10, 5, null), "blah"); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isFalse); |
| expect(suggestions.first.toString(), equals('<null attr="blah"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestWildcardProperty() { |
| final selector = new AttributeContainsSelector( |
| new AngularElementImpl('attr', 10, 5, null), "value"); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isFalse); |
| // [attr*=x] tells us they at LEAST want attr=x |
| expect(suggestions.first.toString(), equals('<null attr="value"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestContainsIsInvalid() { |
| final selector = new ContainsSelector("foo"); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isFalse); |
| // we could assert that it can't be made valid by adding a name, |
| // but :contains is only allowed if it comprises the WHOLE selector (which |
| // is admittedly not as well as the angular team coulddo and might change, |
| // but :contains is so rare we can leave this). |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestRegexPropertyValueNoops() { |
| final selector = new AttributeValueRegexSelector("foo"); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isFalse); |
| expect(suggestions.first.toString(), |
| equals(new HtmlTagForSelector().toString())); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestAndMergesSuggestionConstraints() { |
| final nameSelector = |
| new ElementNameSelector(new AngularElementImpl('panel', 10, 5, null)); |
| final attrSelector = new AttributeContainsSelector( |
| new AngularElementImpl('attr', 10, 5, null), "value"); |
| final selector = new AndSelector([nameSelector, attrSelector]); |
| |
| final suggestions = selector.suggestTags(); |
| expect(suggestions.length, 1); |
| expect(suggestions.first.isValid, isTrue); |
| expect(suggestions.first.toString(), equals('<panel attr="value"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestOrMergesSuggestionConstraints() { |
| final nameSelector = |
| new ElementNameSelector(new AngularElementImpl('panel', 10, 5, null)); |
| final attrSelector = new AttributeContainsSelector( |
| new AngularElementImpl('attr', 10, 5, null), "value"); |
| final selector = new OrSelector([nameSelector, attrSelector]); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 2); |
| final suggestionsMap = <String, HtmlTagForSelector>{}; |
| suggestions.forEach((s) => suggestionsMap[s.toString()] = s); |
| expect(suggestionsMap["<panel"], isNotNull); |
| expect(suggestionsMap["<panel"].isValid, isTrue); |
| expect(suggestionsMap['<null attr="value"'], isNotNull); |
| expect(suggestionsMap['<null attr="value"'].isValid, isFalse); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestOrAnd() { |
| final nameSelector1 = |
| new ElementNameSelector(new AngularElementImpl('name1', 10, 5, null)); |
| final attrSelector1 = new AttributeContainsSelector( |
| new AngularElementImpl('attr1', 10, 5, null), "value"); |
| final andSelector1 = new AndSelector([nameSelector1, attrSelector1]); |
| final nameSelector2 = |
| new ElementNameSelector(new AngularElementImpl('name2', 10, 5, null)); |
| final attrSelector2 = new AttributeContainsSelector( |
| new AngularElementImpl('attr2', 10, 5, null), "value"); |
| final andSelector2 = new AndSelector([nameSelector2, attrSelector2]); |
| final selector = new OrSelector([andSelector1, andSelector2]); |
| |
| final suggestions = selector.suggestTags(); |
| expect(suggestions.length, 2); |
| final suggestionsMap = <String, HtmlTagForSelector>{}; |
| suggestions.forEach((s) => suggestionsMap[s.toString()] = s); |
| expect(suggestionsMap['<name1 attr1="value"'], isNotNull); |
| expect(suggestionsMap['<name2 attr2="value"'], isNotNull); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestAndOr() { |
| final nameSelector1 = |
| new ElementNameSelector(new AngularElementImpl('name1', 10, 5, null)); |
| final nameSelector2 = |
| new ElementNameSelector(new AngularElementImpl('name2', 10, 5, null)); |
| final orSelector1 = new OrSelector([nameSelector1, nameSelector2]); |
| |
| final attrSelector1 = new AttributeContainsSelector( |
| new AngularElementImpl('attr1', 10, 5, null), "value"); |
| final attrSelector2 = new AttributeContainsSelector( |
| new AngularElementImpl('attr2', 10, 5, null), "value"); |
| final orSelector2 = new OrSelector([attrSelector1, attrSelector2]); |
| |
| final selector = new AndSelector([orSelector1, orSelector2]); |
| |
| final suggestions = selector.suggestTags(); |
| expect(suggestions.length, 4); |
| final suggestionsMap = <String, HtmlTagForSelector>{}; |
| suggestions.forEach((s) => suggestionsMap[s.toString()] = s); |
| |
| // basically (name1, name2)(attr1, attr2) though I'm not sure that's legal |
| expect(suggestionsMap['<name1 attr1="value"'], isNotNull); |
| expect(suggestionsMap['<name1 attr2="value"'], isNotNull); |
| expect(suggestionsMap['<name2 attr1="value"'], isNotNull); |
| expect(suggestionsMap['<name2 attr2="value"'], isNotNull); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_suggestOrOr() { |
| final nameSelector1 = |
| new ElementNameSelector(new AngularElementImpl('name1', 10, 5, null)); |
| final nameSelector2 = |
| new ElementNameSelector(new AngularElementImpl('name2', 10, 5, null)); |
| final orSelector1 = new OrSelector([nameSelector1, nameSelector2]); |
| |
| final attrSelector1 = new AttributeContainsSelector( |
| new AngularElementImpl('attr1', 10, 5, null), "value"); |
| final attrSelector2 = new AttributeContainsSelector( |
| new AngularElementImpl('attr2', 10, 5, null), "value"); |
| final orSelector2 = new OrSelector([attrSelector1, attrSelector2]); |
| |
| final selector = new OrSelector([orSelector1, orSelector2]); |
| |
| final suggestions = _evenInvalidSuggestions(selector); |
| expect(suggestions.length, 4); |
| final suggestionsMap = <String, HtmlTagForSelector>{}; |
| suggestions.forEach((s) => suggestionsMap[s.toString()] = s); |
| |
| // basically (name1, name2),(attr1, attr2) though I'm not sure that's legal |
| expect(suggestionsMap['<name1'], isNotNull); |
| expect(suggestionsMap['<null attr2="value"'], isNotNull); |
| expect(suggestionsMap['<name2'], isNotNull); |
| expect(suggestionsMap['<null attr2="value"'], isNotNull); |
| } |
| |
| /// [refineTagSuggestions] filters out invalid tags, but those are important |
| /// for us to test sometimes. This will do the same thing, but keep invalid |
| /// suggestions so we can inspect them. |
| List<HtmlTagForSelector> _evenInvalidSuggestions(Selector selector) { |
| final tags = <HtmlTagForSelector>[new HtmlTagForSelector()]; |
| return selector.refineTagSuggestions(tags); |
| } |
| } |
| |
| @reflectiveTest |
| class HtmlTagForSelectorTest { |
| // ignore: non_constant_identifier_names |
| void test_noNameIsInvalid() { |
| final tag = new HtmlTagForSelector(); |
| expect(tag.isValid, isFalse); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setName() { |
| final tag = new HtmlTagForSelector()..name = "myname"; |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals("<myname")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setNameTwice() { |
| final tag = new HtmlTagForSelector()..name = "myname"; |
| // ignore: cascade_invocations |
| tag.name = "myname"; |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals("<myname")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setNameConflicting() { |
| final tag = new HtmlTagForSelector()..name = "myname1"; |
| // ignore: cascade_invocations |
| tag.name = "myname2"; |
| expect(tag.isValid, isFalse); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setAttributeNoValue() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals("<tagname attr")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setAttributeNoValueTwice() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr"); |
| // ignore: cascade_invocations |
| tag.setAttribute("attr"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals("<tagname attr")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setAttributeValue() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr", value: "value"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname attr="value"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setAttributeValueTwice() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr", value: "value"); |
| // ignore: cascade_invocations |
| tag.setAttribute("attr", value: "value"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname attr="value"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setAttributeValueAfterJustAttr() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr"); |
| // ignore: cascade_invocations |
| tag.setAttribute("attr", value: "value"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname attr="value"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setAttributeNoValueAfterValue() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr", value: "value"); |
| // ignore: cascade_invocations |
| tag.setAttribute("attr"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname attr="value"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_setAttributeConflictingValues() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr", value: "value1"); |
| // ignore: cascade_invocations |
| tag.setAttribute("attr", value: "value2"); |
| expect(tag.isValid, isFalse); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_addClassOneClass() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("myclass"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname class="myclass"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_addClassTwoClasses() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("myclass"); |
| // ignore: cascade_invocations |
| tag.addClass("myotherclass"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname class="myclass myotherclass"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_addClassMultipleTimesOKDoesntRepeat() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("myclass"); |
| // ignore: cascade_invocations |
| tag.addClass("myclass"); |
| // ignore: cascade_invocations |
| tag.addClass("myclass"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname class="myclass"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_classesAndClassAttrBindingInvalid() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("myclass") |
| ..setAttribute("class", value: "blah"); |
| expect(tag.isValid, isFalse); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_classesAndEmptyClassAttrBindingValid() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("myclass") |
| ..setAttribute("class"); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname class="myclass"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_classesAndMatchingClassAttrBindingValid() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("myclass") |
| ..setAttribute("class", value: 'myclass'); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname class="myclass"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneKeepsName() { |
| var tag = new HtmlTagForSelector()..name = "tagname"; |
| tag = tag.clone(); |
| expect(tag.toString(), equals("<tagname")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneKeepsAttributes() { |
| var tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr1") |
| ..setAttribute("attr2"); |
| tag = tag.clone(); |
| expect(tag.toString(), equals("<tagname attr1 attr2")); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneKeepsAttributeValues() { |
| var tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("attr1", value: 'value1') |
| ..setAttribute("attr2", value: 'value2'); |
| tag = tag.clone(); |
| expect(tag.toString(), equals('<tagname attr1="value1" attr2="value2"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneKeepsClassnames() { |
| var tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("class1") |
| ..addClass("class2"); |
| tag = tag.clone(); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), equals('<tagname class="class1 class2"')); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneKeepsValid() { |
| var tag = new HtmlTagForSelector()..name = "tagname"; |
| |
| // ignore: cascade_invocations |
| tag.name = "break this tag"; |
| |
| // ignore: cascade_invocations |
| tag = tag.clone(); |
| expect(tag.isValid, isFalse); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneWithoutNameCanBecomeValid() { |
| var tag = new HtmlTagForSelector(); |
| tag = tag.clone()..name = "tagname"; |
| expect(tag.isValid, isTrue); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneIsAClone() { |
| final tag = new HtmlTagForSelector(); |
| final clone = tag.clone(); |
| tag.name = "original"; |
| clone.name = "clone"; |
| expect(tag, isNot(equals(clone))); |
| expect(tag.isValid, isTrue); |
| expect(tag.toString(), "<original"); |
| expect(clone.isValid, isTrue); |
| expect(clone.toString(), "<clone"); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneHasItsOwnProperties() { |
| final tag = new HtmlTagForSelector()..name = "tagname"; |
| final clone = tag.clone()..setAttribute("attr"); |
| expect(tag.toString(), "<tagname"); |
| expect(clone.toString(), "<tagname attr"); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_cloneHasItsOwnClasses() { |
| final tag = new HtmlTagForSelector()..name = "tagname"; |
| final clone = tag.clone()..addClass("myclass"); |
| expect(tag.toString(), "<tagname"); |
| expect(clone.toString(), '<tagname class="myclass"'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toStringIsAlphabeticalProperties() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..setAttribute("apple") |
| ..setAttribute("flick") |
| ..setAttribute("ziggy") |
| ..setAttribute("cow") |
| ..addClass("classes"); |
| expect(tag.toString(), '<tagname apple class="classes" cow flick ziggy'); |
| } |
| |
| // ignore: non_constant_identifier_names |
| void test_toStringIsAlphabeticalClasses() { |
| final tag = new HtmlTagForSelector() |
| ..name = "tagname" |
| ..addClass("apple") |
| ..addClass("flick") |
| ..addClass("ziggy") |
| ..addClass("cow"); |
| expect(tag.toString(), '<tagname class="apple cow flick ziggy"'); |
| } |
| } |
| |
| class _ElementViewMock extends Mock implements ElementView {} |
| |
| class _SelectorMock extends Mock implements Selector { |
| final String text; |
| |
| _SelectorMock(this.text); |
| |
| @override |
| String toString() => text; |
| } |
| |
| class _SelectorTest { |
| ElementView element = new _ElementViewMock(); |
| Template template = new _TemplateMock(); |
| |
| List<ResolvedRange> resolvedRanges = <ResolvedRange>[]; |
| |
| void setUp() { |
| // TODO(mfairhurst): remove `as dynamic`. See https://github.com/dart-lang/sdk/issues/33934 |
| when(template.addRange(typed(any), typed(any)) as dynamic) |
| .thenAnswer((invocation) { |
| final range = invocation.positionalArguments[0] as SourceRange; |
| final element = invocation.positionalArguments[1] as AngularElement; |
| resolvedRanges.add(new ResolvedRange(range, element)); |
| }); |
| } |
| |
| void _assertRange(ResolvedRange resolvedRange, int offset, int length, |
| AngularElement element) { |
| final range = resolvedRange.range; |
| expect(range.offset, offset); |
| expect(range.length, length); |
| expect(resolvedRange.element, element); |
| } |
| |
| SourceRange _newStringSpan(int offset, String value) => |
| new SourceRange(offset, value.length); |
| } |
| |
| class _SourceMock extends Mock implements Source {} |
| |
| class _TemplateMock extends Mock implements Template {} |