Revision b4522263c308a0f968425a05993bd1a66a09d720 authored by Victor Berchet on 11 December 2015, 02:14:50 UTC, committed by Victor Berchet on 11 December 2015, 02:14:50 UTC
1 parent bbf9483
selector_spec.dart
library angular2.test.compiler.selector_spec;
import "package:angular2/testing_internal.dart"
show describe, it, expect, beforeEach, ddescribe, iit, xit, el;
import "package:angular2/src/platform/dom/dom_adapter.dart" show DOM;
import "package:angular2/src/compiler/selector.dart" show SelectorMatcher;
import "package:angular2/src/compiler/selector.dart" show CssSelector;
import "package:angular2/src/facade/collection.dart"
show ListWrapper, MapWrapper;
main() {
describe("SelectorMatcher", () {
var matcher, selectableCollector, s1, s2, s3, s4;
List<dynamic> matched;
reset() {
matched = [];
}
beforeEach(() {
reset();
s1 = s2 = s3 = s4 = null;
selectableCollector = (selector, context) {
matched.add(selector);
matched.add(context);
};
matcher = new SelectorMatcher();
});
it("should select by element name case sensitive", () {
matcher.addSelectables(s1 = CssSelector.parse("someTag"), 1);
expect(matcher.match(
CssSelector.parse("SOMEOTHERTAG")[0], selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse("SOMETAG")[0], selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse("someTag")[0], selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1]);
});
it("should select by class name case insensitive", () {
matcher.addSelectables(s1 = CssSelector.parse(".someClass"), 1);
matcher.addSelectables(s2 = CssSelector.parse(".someClass.class2"), 2);
expect(matcher.match(
CssSelector.parse(".SOMEOTHERCLASS")[0], selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse(".SOMECLASS")[0], selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1]);
reset();
expect(matcher.match(
CssSelector.parse(".someClass.class2")[0], selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
});
it("should select by attr name case sensitive independent of the value",
() {
matcher.addSelectables(s1 = CssSelector.parse("[someAttr]"), 1);
matcher.addSelectables(
s2 = CssSelector.parse("[someAttr][someAttr2]"), 2);
expect(matcher.match(
CssSelector.parse("[SOMEOTHERATTR]")[0], selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse("[SOMEATTR]")[0], selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(CssSelector.parse("[SOMEATTR=someValue]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(CssSelector.parse("[someAttr][someAttr2]")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(
CssSelector.parse("[someAttr=someValue][someAttr2]")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(
CssSelector.parse("[someAttr2][someAttr=someValue]")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(
CssSelector.parse("[someAttr2=someValue][someAttr]")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
});
it("should select by attr name only once if the value is from the DOM", () {
matcher.addSelectables(s1 = CssSelector.parse("[some-decor]"), 1);
var elementSelector = new CssSelector();
var element = el("<div attr></div>");
var empty = DOM.getAttribute(element, "attr");
elementSelector.addAttribute("some-decor", empty);
matcher.match(elementSelector, selectableCollector);
expect(matched).toEqual([s1[0], 1]);
});
it("should select by attr name case sensitive and value case insensitive",
() {
matcher.addSelectables(s1 = CssSelector.parse("[someAttr=someValue]"), 1);
expect(matcher.match(CssSelector.parse("[SOMEATTR=SOMEOTHERATTR]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(CssSelector.parse("[SOMEATTR=SOMEVALUE]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(CssSelector.parse("[someAttr=SOMEVALUE]")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1]);
});
it("should select by element name, class name and attribute name with value",
() {
matcher.addSelectables(
s1 = CssSelector.parse("someTag.someClass[someAttr=someValue]"), 1);
expect(matcher.match(
CssSelector.parse("someOtherTag.someOtherClass[someOtherAttr]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse("someTag.someOtherClass[someOtherAttr]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse("someTag.someClass[someOtherAttr]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(CssSelector.parse("someTag.someClass[someAttr]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse("someTag.someClass[someAttr=someValue]")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1]);
});
it("should select by many attributes and independent of the value", () {
matcher.addSelectables(
s1 = CssSelector.parse("input[type=text][control]"), 1);
var cssSelector = new CssSelector();
cssSelector.setElement("input");
cssSelector.addAttribute("type", "text");
cssSelector.addAttribute("control", "one");
expect(matcher.match(cssSelector, selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1]);
});
it("should select independent of the order in the css selector", () {
matcher.addSelectables(s1 = CssSelector.parse("[someAttr].someClass"), 1);
matcher.addSelectables(s2 = CssSelector.parse(".someClass[someAttr]"), 2);
matcher.addSelectables(s3 = CssSelector.parse(".class1.class2"), 3);
matcher.addSelectables(s4 = CssSelector.parse(".class2.class1"), 4);
expect(matcher.match(CssSelector.parse("[someAttr].someClass")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(CssSelector.parse(".someClass[someAttr]")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(
CssSelector.parse(".class1.class2")[0], selectableCollector))
.toEqual(true);
expect(matched).toEqual([s3[0], 3, s4[0], 4]);
reset();
expect(matcher.match(
CssSelector.parse(".class2.class1")[0], selectableCollector))
.toEqual(true);
expect(matched).toEqual([s4[0], 4, s3[0], 3]);
});
it("should not select with a matching :not selector", () {
matcher.addSelectables(CssSelector.parse("p:not(.someClass)"), 1);
matcher.addSelectables(CssSelector.parse("p:not([someAttr])"), 2);
matcher.addSelectables(CssSelector.parse(":not(.someClass)"), 3);
matcher.addSelectables(CssSelector.parse(":not(p)"), 4);
matcher.addSelectables(CssSelector.parse(":not(p[someAttr])"), 5);
expect(matcher.match(CssSelector.parse("p.someClass[someAttr]")[0],
selectableCollector)).toEqual(false);
expect(matched).toEqual([]);
});
it("should select with a non matching :not selector", () {
matcher.addSelectables(s1 = CssSelector.parse("p:not(.someClass)"), 1);
matcher.addSelectables(
s2 = CssSelector.parse("p:not(.someOtherClass[someAttr])"), 2);
matcher.addSelectables(s3 = CssSelector.parse(":not(.someClass)"), 3);
matcher.addSelectables(
s4 = CssSelector.parse(":not(.someOtherClass[someAttr])"), 4);
expect(matcher.match(
CssSelector.parse("p[someOtherAttr].someOtherClass")[0],
selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2, s3[0], 3, s4[0], 4]);
});
it("should match with multiple :not selectors", () {
matcher.addSelectables(
s1 = CssSelector.parse("div:not([a]):not([b])"), 1);
expect(matcher.match(CssSelector.parse("div[a]")[0], selectableCollector))
.toBe(false);
expect(matcher.match(CssSelector.parse("div[b]")[0], selectableCollector))
.toBe(false);
expect(matcher.match(CssSelector.parse("div[c]")[0], selectableCollector))
.toBe(true);
});
it("should select with one match in a list", () {
matcher.addSelectables(
s1 = CssSelector.parse("input[type=text], textbox"), 1);
expect(matcher.match(
CssSelector.parse("textbox")[0], selectableCollector)).toEqual(true);
expect(matched).toEqual([s1[1], 1]);
reset();
expect(matcher.match(
CssSelector.parse("input[type=text]")[0], selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1]);
});
it("should not select twice with two matches in a list", () {
matcher.addSelectables(s1 = CssSelector.parse("input, .someClass"), 1);
expect(matcher.match(
CssSelector.parse("input.someclass")[0], selectableCollector))
.toEqual(true);
expect(matched.length).toEqual(2);
expect(matched).toEqual([s1[0], 1]);
});
});
describe("CssSelector.parse", () {
it("should detect element names", () {
var cssSelector = CssSelector.parse("sometag")[0];
expect(cssSelector.element).toEqual("sometag");
expect(cssSelector.toString()).toEqual("sometag");
});
it("should detect class names", () {
var cssSelector = CssSelector.parse(".someClass")[0];
expect(cssSelector.classNames).toEqual(["someclass"]);
expect(cssSelector.toString()).toEqual(".someclass");
});
it("should detect attr names", () {
var cssSelector = CssSelector.parse("[attrname]")[0];
expect(cssSelector.attrs).toEqual(["attrname", ""]);
expect(cssSelector.toString()).toEqual("[attrname]");
});
it("should detect attr values", () {
var cssSelector = CssSelector.parse("[attrname=attrvalue]")[0];
expect(cssSelector.attrs).toEqual(["attrname", "attrvalue"]);
expect(cssSelector.toString()).toEqual("[attrname=attrvalue]");
});
it("should detect multiple parts", () {
var cssSelector =
CssSelector.parse("sometag[attrname=attrvalue].someclass")[0];
expect(cssSelector.element).toEqual("sometag");
expect(cssSelector.attrs).toEqual(["attrname", "attrvalue"]);
expect(cssSelector.classNames).toEqual(["someclass"]);
expect(cssSelector.toString())
.toEqual("sometag.someclass[attrname=attrvalue]");
});
it("should detect multiple attributes", () {
var cssSelector = CssSelector.parse("input[type=text][control]")[0];
expect(cssSelector.element).toEqual("input");
expect(cssSelector.attrs).toEqual(["type", "text", "control", ""]);
expect(cssSelector.toString()).toEqual("input[type=text][control]");
});
it("should detect :not", () {
var cssSelector =
CssSelector.parse("sometag:not([attrname=attrvalue].someclass)")[0];
expect(cssSelector.element).toEqual("sometag");
expect(cssSelector.attrs.length).toEqual(0);
expect(cssSelector.classNames.length).toEqual(0);
var notSelector = cssSelector.notSelectors[0];
expect(notSelector.element).toEqual(null);
expect(notSelector.attrs).toEqual(["attrname", "attrvalue"]);
expect(notSelector.classNames).toEqual(["someclass"]);
expect(cssSelector.toString())
.toEqual("sometag:not(.someclass[attrname=attrvalue])");
});
it("should detect :not without truthy", () {
var cssSelector =
CssSelector.parse(":not([attrname=attrvalue].someclass)")[0];
expect(cssSelector.element).toEqual("*");
var notSelector = cssSelector.notSelectors[0];
expect(notSelector.attrs).toEqual(["attrname", "attrvalue"]);
expect(notSelector.classNames).toEqual(["someclass"]);
expect(cssSelector.toString())
.toEqual("*:not(.someclass[attrname=attrvalue])");
});
it("should throw when nested :not", () {
expect(() {
CssSelector.parse("sometag:not(:not([attrname=attrvalue].someclass))")[
0];
}).toThrowError("Nesting :not is not allowed in a selector");
});
it("should throw when multiple selectors in :not", () {
expect(() {
CssSelector.parse("sometag:not(a,b)");
}).toThrowError("Multiple selectors in :not are not supported");
});
it("should detect lists of selectors", () {
var cssSelectors =
CssSelector.parse(".someclass,[attrname=attrvalue], sometag");
expect(cssSelectors.length).toEqual(3);
expect(cssSelectors[0].classNames).toEqual(["someclass"]);
expect(cssSelectors[1].attrs).toEqual(["attrname", "attrvalue"]);
expect(cssSelectors[2].element).toEqual("sometag");
});
it("should detect lists of selectors with :not", () {
var cssSelectors = CssSelector
.parse("input[type=text], :not(textarea), textbox:not(.special)");
expect(cssSelectors.length).toEqual(3);
expect(cssSelectors[0].element).toEqual("input");
expect(cssSelectors[0].attrs).toEqual(["type", "text"]);
expect(cssSelectors[1].element).toEqual("*");
expect(cssSelectors[1].notSelectors[0].element).toEqual("textarea");
expect(cssSelectors[2].element).toEqual("textbox");
expect(cssSelectors[2].notSelectors[0].classNames).toEqual(["special"]);
});
});
describe("CssSelector.getMatchingElementTemplate", () {
it("should create an element with a tagName, classes, and attributes with the correct casing",
() {
var selector =
CssSelector.parse("Blink.neon.hotpink[Sweet][Dismissable=false]")[0];
var template = selector.getMatchingElementTemplate();
expect(template).toEqual(
"<Blink class=\"neon hotpink\" Sweet Dismissable=\"false\"></Blink>");
});
it("should create an element without a tag name", () {
var selector = CssSelector.parse("[fancy]")[0];
var template = selector.getMatchingElementTemplate();
expect(template).toEqual("<div fancy></div>");
});
it("should ignore :not selectors", () {
var selector = CssSelector.parse("grape:not(.red)")[0];
var template = selector.getMatchingElementTemplate();
expect(template).toEqual("<grape></grape>");
});
});
}
Computing file changes ...