Modified:
/trunk/Fizzler/HumanReadableSelectorGenerator.cs
/trunk/Fizzler/ISelectorGenerator.cs
/trunk/Fizzler/Parser.cs
/trunk/Fizzler/SelectorGenerator.cs
/trunk/Fizzler/SelectorGeneratorTee.cs
/trunk/Fizzler.Sandbox/WinForms/ControlOps.cs
/trunk/Fizzler.Sandbox/Xml/XmlNodeOps.cs
/trunk/Fizzler.Systems.HtmlAgilityPack/HtmlNodeOps.cs
/trunk/Fizzler.Tests/NthLastChild.cs
/trunk/Fizzler.Tests/ParserTests.cs
/trunk/Fizzler.Tests/SelectorGeneratorTeeTests.cs
=======================================
--- /trunk/Fizzler/HumanReadableSelectorGenerator.cs Wed Oct 6 16:15:18
2010
+++ /trunk/Fizzler/HumanReadableSelectorGenerator.cs Wed Oct 6 16:35:37
2010
@@ -2,239 +2,239 @@
{
using System;
- /// <summary>
+ /// <summary>
/// An <see cref="ISelectorGenerator"/> implementation that generates
/// human-readable description of the selector.
- /// </summary>
- public class HumanReadableSelectorGenerator : ISelectorGenerator
- {
- private int _chainCount;
+ /// </summary>
+ public class HumanReadableSelectorGenerator : ISelectorGenerator
+ {
+ private int _chainCount;
private string _text;
/// <summary>
/// Initializes the text.
/// </summary>
public virtual void OnInit()
- {
- Text = null;
- }
-
- /// <summary>
- /// Gets the generated human-readable description text.
- /// </summary>
- public string Text
- {
- get { return _text; }
- private set { _text = value; }
- }
+ {
+ Text = null;
+ }
+
+ /// <summary>
+ /// Gets the generated human-readable description text.
+ /// </summary>
+ public string Text
+ {
+ get { return _text; }
+ private set { _text = value; }
+ }
/// <summary>
/// Generates human-readable for a selector in a group.
/// </summary>
public virtual void OnSelector()
- {
- if (string.IsNullOrEmpty(Text))
- Text = "Take all";
- else
- Text += " and select them. Combined with previous, take all";
- }
-
- /// <summary>
- /// Concludes the text.
- /// </summary>
- public virtual void OnClose()
- {
- Text = Text.Trim();
- Text += " and select them.";
- }
-
- /// <summary>
- /// Adds to the generated human-readable text.
- /// </summary>
- protected void Add(string selector)
- {
- if (selector == null) throw new ArgumentNullException("selector");
- Text += selector;
- }
+ {
+ if (string.IsNullOrEmpty(Text))
+ Text = "Take all";
+ else
+ Text += " and select them. Combined with previous, take
all";
+ }
+
+ /// <summary>
+ /// Concludes the text.
+ /// </summary>
+ public virtual void OnClose()
+ {
+ Text = Text.Trim();
+ Text += " and select them.";
+ }
+
+ /// <summary>
+ /// Adds to the generated human-readable text.
+ /// </summary>
+ protected void Add(string selector)
+ {
+ if (selector == null) throw new
ArgumentNullException("selector");
+ Text += selector;
+ }
/// <summary>
/// Generates human-readable text of this type selector.
/// </summary>
public void Type(NamespacePrefix prefix, string type)
- {
- Add(string.Format(" <{0}> elements", type));
- }
+ {
+ Add(string.Format(" <{0}> elements", type));
+ }
/// <summary>
/// Generates human-readable text of this universal selector.
/// </summary>
public void Universal(NamespacePrefix prefix)
- {
- Add(" elements");
- }
+ {
+ Add(" elements");
+ }
/// <summary>
/// Generates human-readable text of this ID selector.
/// </summary>
public void Id(string id)
- {
- Add(string.Format(" with an ID of '{0}'", id));
- }
+ {
+ Add(string.Format(" with an ID of '{0}'", id));
+ }
/// <summary>
/// Generates human-readable text of this class selector.
/// </summary>
void ISelectorGenerator.Class(string clazz)
- {
- Add(string.Format(" with a class of '{0}'", clazz));
- }
+ {
+ Add(string.Format(" with a class of '{0}'", clazz));
+ }
/// <summary>
/// Generates human-readable text of this attribute selector.
/// </summary>
public void AttributeExists(NamespacePrefix prefix, string name)
- {
+ {
Add(string.Format(" which have attribute {0} defined", name));
- }
+ }
/// <summary>
/// Generates human-readable text of this attribute selector.
/// </summary>
public void AttributeExact(NamespacePrefix prefix, string name,
string value)
- {
- Add(string.Format(" which have attribute {0} with a value of '{1}'",
name, value));
- }
+ {
+ Add(string.Format(" which have attribute {0} with a value
of '{1}'", name, value));
+ }
/// <summary>
/// Generates human-readable text of this attribute selector.
/// </summary>
public void AttributeIncludes(NamespacePrefix prefix, string name,
string value)
- {
- Add(string.Format(" which have attribute {0} that includes the
word '{1}'", name, value));
- }
+ {
+ Add(string.Format(" which have attribute {0} that includes the
word '{1}'", name, value));
+ }
/// <summary>
/// Generates human-readable text of this attribute selector.
/// </summary>
public void AttributeDashMatch(NamespacePrefix prefix, string
name, string value)
- {
- Add(string.Format(" which have attribute {0} with a hyphen separated
value matching '{1}'", name, value));
- }
+ {
+ Add(string.Format(" which have attribute {0} with a hyphen
separated value matching '{1}'", name, value));
+ }
/// <summary>
/// Generates human-readable text of this attribute selector.
/// </summary>
public void AttributePrefixMatch(NamespacePrefix prefix, string
name, string value)
- {
- Add(string.Format(" which have attribute {0} whose value begins
with '{1}'", name, value));
+ {
+ Add(string.Format(" which have attribute {0} whose value
begins with '{1}'", name, value));
}
/// <summary>
/// Generates human-readable text of this attribute selector.
/// </summary>
public void AttributeSuffixMatch(NamespacePrefix prefix, string
name, string value)
- {
- Add(string.Format(" which have attribute {0} whose value ends
with '{1}'", name, value));
+ {
+ Add(string.Format(" which have attribute {0} whose value ends
with '{1}'", name, value));
}
/// <summary>
/// Generates human-readable text of this attribute selector.
/// </summary>
public void AttributeSubstring(NamespacePrefix prefix, string
name, string value)
- {
- Add(string.Format(" which have attribute {0} whose value
contains '{1}'", name, value));
+ {
+ Add(string.Format(" which have attribute {0} whose value
contains '{1}'", name, value));
}
/// <summary>
/// Generates human-readable text of this pseudo-class selector.
/// </summary>
public void FirstChild()
- {
- Add(" which are the first child of their parent");
- }
+ {
+ Add(" which are the first child of their parent");
+ }
/// <summary>
/// Generates human-readable text of this pseudo-class selector.
/// </summary>
public void LastChild()
- {
- Add(" which are the last child of their parent");
- }
+ {
+ Add(" which are the last child of their parent");
+ }
/// <summary>
/// Generates human-readable text of this pseudo-class selector.
/// </summary>
public void NthChild(int a, int b)
- {
- Add(string.Format(" where the element has {0}n+{1}-1 sibling before
it", a, b));
- }
+ {
+ Add(string.Format(" where the element has {0}n+{1}-1 sibling
before it", a, b));
+ }
/// <summary>
/// Generates human-readable text of this pseudo-class selector.
/// </summary>
public void OnlyChild()
- {
- Add(" where the element is the only child");
- }
+ {
+ Add(" where the element is the only child");
+ }
/// <summary>
/// Generates human-readable text of this pseudo-class selector.
/// </summary>
public void Empty()
- {
- Add(" where the element is empty");
- }
+ {
+ Add(" where the element is empty");
+ }
/// <summary>
/// Generates human-readable text of this combinator.
/// </summary>
public void Child()
- {
- Add(", then take their immediate children which are");
- }
+ {
+ Add(", then take their immediate children which are");
+ }
/// <summary>
/// Generates human-readable text of this combinator.
/// </summary>
public void Descendant()
- {
- if (_chainCount > 0)
- {
- Add(". With those, take only their descendants which are");
- }
- else
- {
- Add(", then take their descendants which are");
- _chainCount++;
- }
- }
+ {
+ if (_chainCount > 0)
+ {
+ Add(". With those, take only their descendants which are");
+ }
+ else
+ {
+ Add(", then take their descendants which are");
+ _chainCount++;
+ }
+ }
/// <summary>
/// Generates human-readable text of this combinator.
/// </summary>
public void Adjacent()
- {
- Add(", then take their immediate siblings which are");
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which separates two sequences of simple selectors. The elements
represented
- /// by the two sequences share the same parent in the document tree and
the
- /// element represented by the first sequence precedes (not necessarily
- /// immediately) the element represented by the second one.
- /// </summary>
- public void GeneralSibling()
- {
- Add(", then take their siblings which are");
- }
-
- /// <summary>
- /// Generates human-readable text of this combinator.
- /// </summary>
- public void NthLastChild(int a, int b)
- {
- Add(string.Format(" where the element has {0}n+{1}-1 sibling after it",
a, b));
- }
- }
-}
+ {
+ Add(", then take their immediate siblings which are");
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public void GeneralSibling()
+ {
+ Add(", then take their siblings which are");
+ }
+
+ /// <summary>
+ /// Generates human-readable text of this combinator.
+ /// </summary>
+ public void NthLastChild(int a, int b)
+ {
+ Add(string.Format(" where the element has {0}n+{1}-1 sibling
after it", a, b));
+ }
+ }
+}
=======================================
--- /trunk/Fizzler/ISelectorGenerator.cs Wed Oct 6 16:15:18 2010
+++ /trunk/Fizzler/ISelectorGenerator.cs Wed Oct 6 16:35:37 2010
@@ -167,19 +167,19 @@
/// </summary>
void Adjacent();
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which separates two sequences of simple selectors. The elements
represented
- /// by the two sequences share the same parent in the document tree and
the
- /// element represented by the first sequence precedes (not necessarily
- /// immediately) the element represented by the second one.
- /// </summary>
- void GeneralSibling();
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that is the N-th child from bottom up of
some other element.
- /// </summary>
- void NthLastChild(int a, int b);
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ void GeneralSibling();
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child from bottom
up of some other element.
+ /// </summary>
+ void NthLastChild(int a, int b);
}
}
=======================================
--- /trunk/Fizzler/Parser.cs Wed Oct 6 16:28:04 2010
+++ /trunk/Fizzler/Parser.cs Wed Oct 6 16:35:37 2010
@@ -19,7 +19,7 @@
{
private readonly Reader<Token> _reader;
private readonly ISelectorGenerator _generator;
-
+
private Parser(Reader<Token> reader, ISelectorGenerator generator)
{
Debug.Assert(reader != null);
@@ -45,7 +45,7 @@
{
if (selectors == null) throw new
ArgumentNullException("selectors");
if (selectors.Length == 0) throw new
ArgumentException(null, "selectors");
-
+
return Parse(Tokener.Tokenize(selectors), generator, resultor);
}
@@ -53,7 +53,7 @@
/// Parses a tokenized stream representing a CSS selector group and
/// generates its implementation.
/// </summary>
- public static TGenerator Parse<TGenerator>(IEnumerable<Token>
tokens, TGenerator generator)
+ public static TGenerator Parse<TGenerator>(IEnumerable<Token>
tokens, TGenerator generator)
where TGenerator : ISelectorGenerator
{
return Parse(tokens, generator, g => g);
@@ -63,12 +63,12 @@
/// Parses a tokenized stream representing a CSS selector group and
/// generates its implementation.
/// </summary>
- public static T Parse<TGenerator, T>(IEnumerable<Token> tokens,
TGenerator generator, Func<TGenerator, T> resultor)
+ public static T Parse<TGenerator, T>(IEnumerable<Token> tokens,
TGenerator generator, Func<TGenerator, T> resultor)
where TGenerator : ISelectorGenerator
{
if (tokens == null) throw new ArgumentNullException("tokens");
- if(resultor == null) throw new
ArgumentNullException("resultor");
-
+ if (resultor == null) throw new
ArgumentNullException("resultor");
+
new Parser(new Reader<Token>(tokens.GetEnumerator()),
generator).Parse();
return resultor(generator);
}
@@ -117,7 +117,7 @@
// ;
var token = TryRead(ToTokenSpec(TokenKind.Plus),
ToTokenSpec(TokenKind.Greater), ToTokenSpec(TokenKind.Tilde),
ToTokenSpec(TokenKind.WhiteSpace));
-
+
if (token == null)
return false;
@@ -136,7 +136,7 @@
TryRead(ToTokenSpec(TokenKind.WhiteSpace));
}
-
+
return true;
}
@@ -162,9 +162,9 @@
}
else
{
- if (modifiers == 0 && !named)
+ if (modifiers == 0 && !named)
_generator.Universal(NamespacePrefix.None); //
implied
-
+
if (token.Value.Kind == TokenKind.Hash)
{
_generator.Id(token.Value.Text);
@@ -214,10 +214,10 @@
case "only-child": _generator.OnlyChild(); break;
case "empty": _generator.Empty(); break;
default:
- {
- throw new FormatException(string.Format(
- "Unknown pseudo-class '{0}'. Use either
first-child, last-child, only-child or empty.", clazz));
- }
+ {
+ throw new FormatException(string.Format(
+ "Unknown pseudo-class '{0}'. Use either
first-child, last-child, only-child or empty.", clazz));
+ }
}
}
}
@@ -238,12 +238,12 @@
switch (func)
{
case "nth-child": Nth(); break;
- case "nth-last-child": NthLast(); break;
+ case "nth-last-child": NthLast(); break;
default:
- {
- throw new FormatException(string.Format(
- "Unknown functional pseudo '{0}'. Only nth-child
and nth-last-child are supported.", func));
- }
+ {
+ throw new FormatException(string.Format(
+ "Unknown functional pseudo '{0}'. Only
nth-child and nth-last-child are supported.", func));
+ }
}
Read(ToTokenSpec(Token.RightParenthesis()));
@@ -264,17 +264,17 @@
}
private void NthLast()
- {
- //nth
- // : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
- // ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
- // ;
-
- // TODO Add support for the full syntax
- // At present, only INTEGER is allowed
-
- _generator.NthLastChild(1, NthB());
- }
+ {
+ //nth
+ // : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER
]? |
+ // ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
+ // ;
+
+ // TODO Add support for the full syntax
+ // At present, only INTEGER is allowed
+
+ _generator.NthLastChild(1, NthB());
+ }
private int NthB()
{
@@ -297,21 +297,21 @@
Read(ToTokenSpec(Token.LeftBracket()));
var prefix = TryNamespacePrefix() ?? NamespacePrefix.None;
var name = Read(ToTokenSpec(TokenKind.Ident)).Text;
-
+
var hasValue = false;
while (true)
{
var op = TryRead(
- ToTokenSpec(Token.Equals()),
- ToTokenSpec(TokenKind.Includes),
- ToTokenSpec(TokenKind.DashMatch),
- ToTokenSpec(TokenKind.PrefixMatch),
+ ToTokenSpec(Token.Equals()),
+ ToTokenSpec(TokenKind.Includes),
+ ToTokenSpec(TokenKind.DashMatch),
+ ToTokenSpec(TokenKind.PrefixMatch),
ToTokenSpec(TokenKind.SuffixMatch),
ToTokenSpec(TokenKind.SubstringMatch));
-
- if(op == null)
+
+ if (op == null)
break;
-
+
hasValue = true;
var value = Read(ToTokenSpec(TokenKind.String),
ToTokenSpec(TokenKind.Ident)).Text;
@@ -331,10 +331,10 @@
}
}
}
-
+
if (!hasValue)
_generator.AttributeExists(prefix, name);
-
+
Read(ToTokenSpec(Token.RightBracket()));
}
@@ -343,7 +343,7 @@
//class
// : '.' IDENT
// ;
-
+
Read(ToTokenSpec(Token.Dot()));
_generator.Class(Read(ToTokenSpec(TokenKind.Ident)).Text);
}
@@ -356,20 +356,20 @@
var pipe = Token.Pipe();
var token = TryRead(ToTokenSpec(TokenKind.Ident),
ToTokenSpec(Token.Star()), ToTokenSpec(pipe));
-
+
if (token == null)
return null;
-
+
if (token.Value == pipe)
return NamespacePrefix.Empty;
-
+
var prefix = token.Value;
if (TryRead(ToTokenSpec(pipe)) == null)
{
Unread(prefix);
return null;
}
-
+
return prefix.Kind == TokenKind.Ident
? new NamespacePrefix(prefix.Text)
: NamespacePrefix.Any;
@@ -418,7 +418,7 @@
if (token == null)
{
throw new FormatException(string.Format(
- @"Unexpected token {{{0}}} where one of [{1}] was
expected.",
+ @"Unexpected token {{{0}}} where one of [{1}] was
expected.",
Peek().Kind, string.Join(", ", specs.Select(k =>
k.ToString()).ToArray())));
}
return token.Value;
=======================================
--- /trunk/Fizzler/SelectorGenerator.cs Wed Oct 6 16:15:18 2010
+++ /trunk/Fizzler/SelectorGenerator.cs Wed Oct 6 16:35:37 2010
@@ -296,25 +296,25 @@
Add(Ops.Adjacent());
}
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which separates two sequences of simple selectors. The elements
represented
- /// by the two sequences share the same parent in the document tree and
the
- /// element represented by the first sequence precedes (not necessarily
- /// immediately) the element represented by the second one.
- /// </summary>
- public virtual void GeneralSibling()
- {
- Add(Ops.GeneralSibling());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that is the N-th child from bottom up of
some other element.
- /// </summary>
- public void NthLastChild(int a, int b)
- {
- Add(Ops.NthLastChild(a, b));
- }
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public virtual void GeneralSibling()
+ {
+ Add(Ops.GeneralSibling());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child from bottom
up of some other element.
+ /// </summary>
+ public void NthLastChild(int a, int b)
+ {
+ Add(Ops.NthLastChild(a, b));
+ }
}
}
=======================================
--- /trunk/Fizzler/SelectorGeneratorTee.cs Wed Oct 6 16:15:18 2010
+++ /trunk/Fizzler/SelectorGeneratorTee.cs Wed Oct 6 16:35:37 2010
@@ -231,22 +231,22 @@
Secondary.Adjacent();
}
- /// <summary>
- /// Delegates to <see cref="Primary"/> then <see cref="Secondary"/>
generator.
- /// </summary>
- public void GeneralSibling()
- {
- Primary.GeneralSibling();
- Secondary.GeneralSibling();
- }
-
- /// <summary>
- /// Delegates to <see cref="Primary"/> then <see cref="Secondary"/>
generator.
- /// </summary>
- public void NthLastChild(int a, int b)
- {
- Primary.NthLastChild(a, b);
- Secondary.NthLastChild(a, b);
- }
+ /// <summary>
+ /// Delegates to <see cref="Primary"/> then <see
cref="Secondary"/> generator.
+ /// </summary>
+ public void GeneralSibling()
+ {
+ Primary.GeneralSibling();
+ Secondary.GeneralSibling();
+ }
+
+ /// <summary>
+ /// Delegates to <see cref="Primary"/> then <see
cref="Secondary"/> generator.
+ /// </summary>
+ public void NthLastChild(int a, int b)
+ {
+ Primary.NthLastChild(a, b);
+ Secondary.NthLastChild(a, b);
+ }
}
}
=======================================
--- /trunk/Fizzler.Sandbox/WinForms/ControlOps.cs Wed Oct 6 16:15:18 2010
+++ /trunk/Fizzler.Sandbox/WinForms/ControlOps.cs Wed Oct 6 16:35:37 2010
@@ -236,21 +236,21 @@
return controls => controls.SelectMany(c =>
c.ControlsAfterSelf().Take(1));
}
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which separates two sequences of simple selectors. The elements
represented
- /// by the two sequences share the same parent in the document tree
and the
- /// element represented by the first sequence precedes (not
necessarily
- /// immediately) the element represented by the second one.
- /// </summary>
- public virtual Selector<Control> GeneralSibling()
- {
- return nodes => nodes.SelectMany(n => n.ControlsAfterSelf());
- }
-
- public Selector<Control> NthLastChild(int a, int b)
- {
- throw new NotImplementedException();
- }
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public virtual Selector<Control> GeneralSibling()
+ {
+ return nodes => nodes.SelectMany(n => n.ControlsAfterSelf());
+ }
+
+ public Selector<Control> NthLastChild(int a, int b)
+ {
+ throw new NotImplementedException();
+ }
}
}
=======================================
--- /trunk/Fizzler.Sandbox/Xml/XmlNodeOps.cs Wed Oct 6 16:15:18 2010
+++ /trunk/Fizzler.Sandbox/Xml/XmlNodeOps.cs Wed Oct 6 16:35:37 2010
@@ -9,201 +9,201 @@
#endregion
public class XmlNodeOps : IElementOps<XmlNode>
- {
- public virtual Selector<XmlNode> Type(NamespacePrefix prefix, string
type)
- {
+ {
+ public virtual Selector<XmlNode> Type(NamespacePrefix prefix,
string type)
+ {
// TODO Proper namespace support
return nodes => nodes.Where(n => n.Name == type);
- }
-
- public virtual Selector<XmlNode> Universal(NamespacePrefix prefix)
- {
+ }
+
+ public virtual Selector<XmlNode> Universal(NamespacePrefix prefix)
+ {
// TODO Proper namespace support
return nodes => nodes.Elements();
- }
-
- public virtual Selector<XmlNode> Id(string id)
- {
- return AttributeExact(NamespacePrefix.None, "id", id);
- }
-
- public virtual Selector<XmlNode> Class(string clazz)
- {
- return AttributeIncludes(NamespacePrefix.None, "class", clazz);
- }
-
- public virtual Selector<XmlNode> AttributeExists(NamespacePrefix prefix,
string name)
- {
+ }
+
+ public virtual Selector<XmlNode> Id(string id)
+ {
+ return AttributeExact(NamespacePrefix.None, "id", id);
+ }
+
+ public virtual Selector<XmlNode> Class(string clazz)
+ {
+ return AttributeIncludes(NamespacePrefix.None, "class", clazz);
+ }
+
+ public virtual Selector<XmlNode> AttributeExists(NamespacePrefix
prefix, string name)
+ {
// TODO Proper namespace support
- return nodes => nodes.Elements().Where(n => n.Attributes[name] != null);
- }
-
- public virtual Selector<XmlNode> AttributeExact(NamespacePrefix prefix,
string name, string value)
- {
+ return nodes => nodes.Elements().Where(n =>
n.Attributes[name] != null);
+ }
+
+ public virtual Selector<XmlNode> AttributeExact(NamespacePrefix
prefix, string name, string value)
+ {
// TODO Proper namespace support
return nodes => from n in nodes.Elements()
- let a = n.Attributes[name]
- where a != null && a.Value == value
- select n;
- }
-
- public virtual Selector<XmlNode> AttributeIncludes(NamespacePrefix
prefix, string name, string value)
- {
+ let a = n.Attributes[name]
+ where a != null && a.Value == value
+ select n;
+ }
+
+ public virtual Selector<XmlNode> AttributeIncludes(NamespacePrefix
prefix, string name, string value)
+ {
// TODO Proper namespace support
return nodes => from n in nodes.Elements()
- let a = n.Attributes[name]
- where a != null && a.Value.Split(' ').Contains(value)
- select n;
- }
-
- public virtual Selector<XmlNode> AttributeDashMatch(NamespacePrefix
prefix, string name, string value)
- {
+ let a = n.Attributes[name]
+ where a != null &&
a.Value.Split(' ').Contains(value)
+ select n;
+ }
+
+ public virtual Selector<XmlNode>
AttributeDashMatch(NamespacePrefix prefix, string name, string value)
+ {
// TODO Proper namespace support
return string.IsNullOrEmpty(value)
- ? (Selector<XmlNode>)(nodes => Enumerable.Empty<XmlNode>())
- : (nodes => from n in nodes.Elements()
- let a = n.Attributes[name]
- where a != null && a.Value.Split('-').Contains(value)
- select n);
- }
-
- public virtual Selector<XmlNode> AttributePrefixMatch(NamespacePrefix
prefix, string name, string value)
- {
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null &&
a.Value.Split('-').Contains(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode>
AttributePrefixMatch(NamespacePrefix prefix, string name, string value)
+ {
// TODO Proper namespace support
return string.IsNullOrEmpty(value)
- ? (Selector<XmlNode>)(nodes => Enumerable.Empty<XmlNode>())
- : (nodes => from n in nodes.Elements()
- let a = n.Attributes[name]
- where a != null && a.Value.StartsWith(value)
- select n);
- }
-
- public virtual Selector<XmlNode> AttributeSuffixMatch(NamespacePrefix
prefix, string name, string value)
- {
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.StartsWith(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode>
AttributeSuffixMatch(NamespacePrefix prefix, string name, string value)
+ {
// TODO Proper namespace support
return string.IsNullOrEmpty(value)
- ? (Selector<XmlNode>)(nodes => Enumerable.Empty<XmlNode>())
- : (nodes => from n in nodes.Elements()
- let a = n.Attributes[name]
- where a != null && a.Value.EndsWith(value)
- select n);
- }
-
- public virtual Selector<XmlNode> AttributeSubstring(NamespacePrefix
prefix, string name, string value)
- {
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.EndsWith(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode>
AttributeSubstring(NamespacePrefix prefix, string name, string value)
+ {
// TODO Proper namespace support
return string.IsNullOrEmpty(value)
- ? (Selector<XmlNode>)(nodes => Enumerable.Empty<XmlNode>())
- : (nodes => from n in nodes.Elements()
- let a = n.Attributes[name]
- where a != null && a.Value.Contains(value)
- select n);
- }
-
- public virtual Selector<XmlNode> FirstChild()
- {
- return nodes => nodes.Where(n => !n.ElementsBeforeSelf().Any());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that is the last child of some other
element.
- /// </summary>
- public virtual Selector<XmlNode> LastChild()
- {
- return nodes => nodes.Where(n => n.ParentNode.NodeType !=
XmlNodeType.Document
- && !n.ElementsAfterSelf().Any());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that is the N-th child of some other
element.
- /// </summary>
- public virtual Selector<XmlNode> NthChild(int a, int b)
- {
- if (a != 1)
- throw new NotSupportedException("The nth-child(an+b) selector where a
in is not 1 are not supported.");
-
- return nodes => from n in nodes
- let elements = n.ParentNode.Elements().Take(b).ToArray()
- where elements.Length == b && elements.Last().Equals(n)
- select n;
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that has a parent element and whose
parent
- /// element has no other element children.
- /// </summary>
- public virtual Selector<XmlNode> OnlyChild()
- {
- return nodes => nodes.Where(n => n.ParentNode.NodeType !=
XmlNodeType.Document
-
&& !n.ElementsAfterSelf().Concat(n.ElementsBeforeSelf()).Any());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that has no children at all.
- /// </summary>
- public virtual Selector<XmlNode> Empty()
- {
- return nodes => nodes.Elements().Where(n => n.ChildNodes.Count == 0);
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which represents a childhood relationship between two elements.
- /// </summary>
- public virtual Selector<XmlNode> Child()
- {
- return nodes => nodes.SelectMany(n => n.Elements());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which represents a relationship between two elements where one
element is an
- /// arbitrary descendant of some ancestor element.
- /// </summary>
- public virtual Selector<XmlNode> Descendant()
- {
- return nodes => nodes.SelectMany(n => n.Descendants().Elements());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which represents elements that share the same parent in the document
tree and
- /// where the first element immediately precedes the second element.
- /// </summary>
- public virtual Selector<XmlNode> Adjacent()
- {
- return nodes => nodes.SelectMany(n => n.ElementsAfterSelf().Take(1));
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which separates two sequences of simple selectors. The elements
represented
- /// by the two sequences share the same parent in the document tree and
the
- /// element represented by the first sequence precedes (not necessarily
- /// immediately) the element represented by the second one.
- /// </summary>
- public virtual Selector<XmlNode> GeneralSibling()
- {
- return nodes => nodes.SelectMany(n => n.ElementsAfterSelf());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that is the N-th child from bottom up of
some other element.
- /// </summary>
- public Selector<XmlNode> NthLastChild(int a, int b)
- {
- if (a != 1)
- throw new NotSupportedException("The nth-last-child(an+b) selector
where a in is not 1 are not supported.");
-
- return nodes => from n in nodes
- let elements = n.ParentNode.Elements().Skip(Math.Max(0,
n.ParentNode.Elements().Count() - b)).Take(b).ToArray()
- where elements.Length == b && elements.First().Equals(n)
- select n;
- }
- }
-}
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.Contains(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode> FirstChild()
+ {
+ return nodes => nodes.Where(n
=> !n.ElementsBeforeSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the last child of some
other element.
+ /// </summary>
+ public virtual Selector<XmlNode> LastChild()
+ {
+ return nodes => nodes.Where(n => n.ParentNode.NodeType !=
XmlNodeType.Document
+ && !n.ElementsAfterSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child of some
other element.
+ /// </summary>
+ public virtual Selector<XmlNode> NthChild(int a, int b)
+ {
+ if (a != 1)
+ throw new NotSupportedException("The nth-child(an+b)
selector where a in is not 1 are not supported.");
+
+ return nodes => from n in nodes
+ let elements =
n.ParentNode.Elements().Take(b).ToArray()
+ where elements.Length == b &&
elements.Last().Equals(n)
+ select n;
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that has a parent element and
whose parent
+ /// element has no other element children.
+ /// </summary>
+ public virtual Selector<XmlNode> OnlyChild()
+ {
+ return nodes => nodes.Where(n => n.ParentNode.NodeType !=
XmlNodeType.Document
+
&& !n.ElementsAfterSelf().Concat(n.ElementsBeforeSelf()).Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that has no children at all.
+ /// </summary>
+ public virtual Selector<XmlNode> Empty()
+ {
+ return nodes => nodes.Elements().Where(n => n.ChildNodes.Count
== 0);
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a childhood relationship between two elements.
+ /// </summary>
+ public virtual Selector<XmlNode> Child()
+ {
+ return nodes => nodes.SelectMany(n => n.Elements());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a relationship between two elements where one
element is an
+ /// arbitrary descendant of some ancestor element.
+ /// </summary>
+ public virtual Selector<XmlNode> Descendant()
+ {
+ return nodes => nodes.SelectMany(n =>
n.Descendants().Elements());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents elements that share the same parent in the
document tree and
+ /// where the first element immediately precedes the second
element.
+ /// </summary>
+ public virtual Selector<XmlNode> Adjacent()
+ {
+ return nodes => nodes.SelectMany(n =>
n.ElementsAfterSelf().Take(1));
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public virtual Selector<XmlNode> GeneralSibling()
+ {
+ return nodes => nodes.SelectMany(n => n.ElementsAfterSelf());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child from bottom
up of some other element.
+ /// </summary>
+ public Selector<XmlNode> NthLastChild(int a, int b)
+ {
+ if (a != 1)
+ throw new NotSupportedException("The nth-last-child(an+b)
selector where a in is not 1 are not supported.");
+
+ return nodes => from n in nodes
+ let elements =
n.ParentNode.Elements().Skip(Math.Max(0, n.ParentNode.Elements().Count() -
b)).Take(b).ToArray()
+ where elements.Length == b &&
elements.First().Equals(n)
+ select n;
+ }
+ }
+}
=======================================
--- /trunk/Fizzler.Systems.HtmlAgilityPack/HtmlNodeOps.cs Wed Oct 6
16:15:18 2010
+++ /trunk/Fizzler.Systems.HtmlAgilityPack/HtmlNodeOps.cs Wed Oct 6
16:35:37 2010
@@ -247,31 +247,31 @@
return nodes => nodes.SelectMany(n =>
n.ElementsAfterSelf().Take(1));
}
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
- /// which separates two sequences of simple selectors. The elements
represented
- /// by the two sequences share the same parent in the document tree
and the
- /// element represented by the first sequence precedes (not
necessarily
- /// immediately) the element represented by the second one.
- /// </summary>
- public virtual Selector<HtmlNode> GeneralSibling()
- {
- return nodes => nodes.SelectMany(n => n.ElementsAfterSelf());
- }
-
- /// <summary>
- /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
- /// which represents an element that is the N-th child from bottom up of
some other element.
- /// </summary>
- public Selector<HtmlNode> NthLastChild(int a, int b)
- {
- if (a != 1)
- throw new NotSupportedException("The nth-last-child(an+b) selector
where a in is not 1 are not supported.");
-
- return nodes => from n in nodes
- let elements = n.ParentNode.Elements().Skip(Math.Max(0,
n.ParentNode.Elements().Count() - b)).Take(b).ToArray()
- where elements.Length == b && elements.First().Equals(n)
- select n;
- }
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public virtual Selector<HtmlNode> GeneralSibling()
+ {
+ return nodes => nodes.SelectMany(n => n.ElementsAfterSelf());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child from bottom
up of some other element.
+ /// </summary>
+ public Selector<HtmlNode> NthLastChild(int a, int b)
+ {
+ if (a != 1)
+ throw new NotSupportedException("The nth-last-child(an+b)
selector where a in is not 1 are not supported.");
+
+ return nodes => from n in nodes
+ let elements =
n.ParentNode.Elements().Skip(Math.Max(0, n.ParentNode.Elements().Count() -
b)).Take(b).ToArray()
+ where elements.Length == b &&
elements.First().Equals(n)
+ select n;
+ }
}
}
=======================================
--- /trunk/Fizzler.Tests/NthLastChild.cs Wed Oct 6 16:15:18 2010
+++ /trunk/Fizzler.Tests/NthLastChild.cs Wed Oct 6 16:35:37 2010
@@ -1,48 +1,48 @@
namespace Fizzler.Tests
{
- using NUnit.Framework;
-
- [TestFixture]
- public class NthLastChild : SelectorBaseTest
- {
- [Test]
- public void No_Prefix_With_Digit()
- {
- var result = SelectList(":nth-last-child(2)");
-
- Assert.AreEqual(4, result.Count);
- Assert.AreEqual("head", result[0].Name);
- Assert.AreEqual("div", result[1].Name);
- Assert.AreEqual("span", result[2].Name);
- Assert.AreEqual("div", result[3].Name);
- }
-
- [Test]
- public void Id_Prefix_With_Digit()
- {
- var result = SelectList("#myDiv :nth-last-child(2)");
-
- Assert.AreEqual(2, result.Count);
- Assert.AreEqual("div", result[0].Name);
- Assert.AreEqual("span", result[1].Name);
- }
-
- [Test]
- public void Element_Prefix_With_Digit()
- {
- var result = SelectList("span:nth-last-child(3)");
-
- Assert.AreEqual(0, result.Count);
- }
-
- [Test]
- public void Element_Prefix_With_Digit2()
- {
- var result = SelectList("span:nth-last-child(2)");
-
- Assert.AreEqual(1, result.Count);
- Assert.AreEqual("span", result[0].Name);
- }
- }
-}
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class NthLastChild : SelectorBaseTest
+ {
+ [Test]
+ public void No_Prefix_With_Digit()
+ {
+ var result = SelectList(":nth-last-child(2)");
+
+ Assert.AreEqual(4, result.Count);
+ Assert.AreEqual("head", result[0].Name);
+ Assert.AreEqual("div", result[1].Name);
+ Assert.AreEqual("span", result[2].Name);
+ Assert.AreEqual("div", result[3].Name);
+ }
+
+ [Test]
+ public void Id_Prefix_With_Digit()
+ {
+ var result = SelectList("#myDiv :nth-last-child(2)");
+
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ Assert.AreEqual("span", result[1].Name);
+ }
+
+ [Test]
+ public void Element_Prefix_With_Digit()
+ {
+ var result = SelectList("span:nth-last-child(3)");
+
+ Assert.AreEqual(0, result.Count);
+ }
+
+ [Test]
+ public void Element_Prefix_With_Digit2()
+ {
+ var result = SelectList("span:nth-last-child(2)");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("span", result[0].Name);
+ }
+ }
+}
=======================================
--- /trunk/Fizzler.Tests/ParserTests.cs Wed Oct 6 16:15:18 2010
+++ /trunk/Fizzler.Tests/ParserTests.cs Wed Oct 6 16:35:37 2010
@@ -484,12 +484,12 @@
throw new NotImplementedException();
}
- public void NthLastChild(int a, int b)
- {
- throw new NotImplementedException();
- }
-
- #endregion
+ public void NthLastChild(int a, int b)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
}
}
}
=======================================
--- /trunk/Fizzler.Tests/SelectorGeneratorTeeTests.cs Wed Oct 6 16:15:18
2010
+++ /trunk/Fizzler.Tests/SelectorGeneratorTeeTests.cs Wed Oct 6 16:35:37
2010
@@ -11,374 +11,374 @@
#endregion
/// <summary>
- /// Ensure that all actions on SelectorGeneratorTee are passed
- /// to the internal Primary and Secondary SelectorGenerators.
- /// </summary>
- [TestFixture]
- public class SelectorGeneratorTeeTests
- {
- private static SelectorGeneratorTee tee;
- private static FakeSelectorGenerator primary;
- private static FakeSelectorGenerator secondary;
-
- [SetUp]
- public void Setup()
- {
- primary = new FakeSelectorGenerator();
- secondary = new FakeSelectorGenerator();
- tee = new SelectorGeneratorTee(primary, secondary);
- }
-
- [Test, ExpectedException(typeof(ArgumentNullException))]
- public void NullPrimary()
- {
- new SelectorGeneratorTee(
- null, new FakeSelectorGenerator()
- );
- }
-
- [Test, ExpectedException(typeof(ArgumentNullException))]
- public void NullSecondary()
- {
- new SelectorGeneratorTee(
- new FakeSelectorGenerator(), null
- );
- }
+ /// Ensure that all actions on SelectorGeneratorTee are passed
+ /// to the internal Primary and Secondary SelectorGenerators.
+ /// </summary>
+ [TestFixture]
+ public class SelectorGeneratorTeeTests
+ {
+ private static SelectorGeneratorTee tee;
+ private static FakeSelectorGenerator primary;
+ private static FakeSelectorGenerator secondary;
+
+ [SetUp]
+ public void Setup()
+ {
+ primary = new FakeSelectorGenerator();
+ secondary = new FakeSelectorGenerator();
+ tee = new SelectorGeneratorTee(primary, secondary);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void NullPrimary()
+ {
+ new SelectorGeneratorTee(
+ null, new FakeSelectorGenerator()
+ );
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void NullSecondary()
+ {
+ new SelectorGeneratorTee(
+ new FakeSelectorGenerator(), null
+ );
+ }
[Test]
- public void OnInitTest()
- {
- Run(tee.OnInit);
- }
-
- [Test]
- public void OnCloseTest()
- {
- Run(tee.OnClose);
- }
-
- [Test]
- public void OnSelectorTest()
- {
- Run(tee.OnSelector);
- }
-
- [Test]
- public void TypeTest()
- {
+ public void OnInitTest()
+ {
+ Run(tee.OnInit);
+ }
+
+ [Test]
+ public void OnCloseTest()
+ {
+ Run(tee.OnClose);
+ }
+
+ [Test]
+ public void OnSelectorTest()
+ {
+ Run(tee.OnSelector);
+ }
+
+ [Test]
+ public void TypeTest()
+ {
Run(tee.Type, NamespacePrefix.None, "go");
- }
-
- [Test]
- public void UniversalTest()
- {
- Run(tee.Universal, NamespacePrefix.None);
- }
-
- [Test]
- public void IdTest()
- {
- Run(tee.Id, "hello");
- }
-
- [Test]
- public void ClassTest()
- {
- Run(tee.Class, "hello");
- }
-
- [Test]
- public void AttrExistsTest()
- {
- Run(tee.AttributeExists, NamespacePrefix.None, "hello");
- }
-
- [Test]
- public void AttExactTest()
- {
- Run(tee.AttributeExact, NamespacePrefix.None, "hello", "there");
- }
-
- [Test]
- public void AttrIncludesTest()
- {
- Run(tee.AttributeIncludes, NamespacePrefix.None, "hello", "there");
- }
-
- [Test]
- public void AttrDashMatchTest()
- {
- Run(tee.AttributeDashMatch, NamespacePrefix.None, "hello", "there");
- }
-
- [Test]
- public void AttrPrefixMatchTest()
- {
- Run(tee.AttributePrefixMatch,NamespacePrefix.None, "hello", "there");
- }
-
- [Test]
- public void AttrSuffixMatchTest()
- {
- Run(tee.AttributeSuffixMatch, NamespacePrefix.None, "hello", "there");
- }
-
- [Test]
- public void AttrSubstringTest()
- {
- Run(tee.AttributeSubstring, NamespacePrefix.None, "hello", "there");
- }
-
- [Test]
- public void FirstChildTest()
- {
- Run(tee.FirstChild);
- }
-
- [Test]
- public void LastChildTest()
- {
- Run(tee.LastChild);
- }
-
- [Test]
- public void NthChildTest()
- {
- Run(tee.NthChild, 1, 2);
- }
-
- [Test]
- public void OnlyChildTest()
- {
- Run(tee.OnlyChild);
- }
-
- [Test]
- public void EmptyTest()
- {
- Run(tee.Empty);
- }
-
- [Test]
- public void ChildTest()
- {
- Run(tee.Child);
- }
-
- [Test]
- public void DescendantTest()
- {
- Run(tee.Descendant);
- }
-
- [Test]
- public void AdjacentTest()
- {
- Run(tee.Adjacent);
- }
-
- [Test]
- public void GeneralSiblingTest()
- {
- Run(tee.GeneralSibling);
- }
-
- private static void Run(Action action)
- {
- RunImpl(action.Method);
- }
+ }
+
+ [Test]
+ public void UniversalTest()
+ {
+ Run(tee.Universal, NamespacePrefix.None);
+ }
+
+ [Test]
+ public void IdTest()
+ {
+ Run(tee.Id, "hello");
+ }
+
+ [Test]
+ public void ClassTest()
+ {
+ Run(tee.Class, "hello");
+ }
+
+ [Test]
+ public void AttrExistsTest()
+ {
+ Run(tee.AttributeExists, NamespacePrefix.None, "hello");
+ }
+
+ [Test]
+ public void AttExactTest()
+ {
+ Run(tee.AttributeExact,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrIncludesTest()
+ {
+ Run(tee.AttributeIncludes,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrDashMatchTest()
+ {
+ Run(tee.AttributeDashMatch,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrPrefixMatchTest()
+ {
+
Run(tee.AttributePrefixMatch,NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrSuffixMatchTest()
+ {
+ Run(tee.AttributeSuffixMatch,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrSubstringTest()
+ {
+ Run(tee.AttributeSubstring,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void FirstChildTest()
+ {
+ Run(tee.FirstChild);
+ }
+
+ [Test]
+ public void LastChildTest()
+ {
+ Run(tee.LastChild);
+ }
+
+ [Test]
+ public void NthChildTest()
+ {
+ Run(tee.NthChild, 1, 2);
+ }
+
+ [Test]
+ public void OnlyChildTest()
+ {
+ Run(tee.OnlyChild);
+ }
+
+ [Test]
+ public void EmptyTest()
+ {
+ Run(tee.Empty);
+ }
+
+ [Test]
+ public void ChildTest()
+ {
+ Run(tee.Child);
+ }
+
+ [Test]
+ public void DescendantTest()
+ {
+ Run(tee.Descendant);
+ }
+
+ [Test]
+ public void AdjacentTest()
+ {
+ Run(tee.Adjacent);
+ }
+
+ [Test]
+ public void GeneralSiblingTest()
+ {
+ Run(tee.GeneralSibling);
+ }
+
+ private static void Run(Action action)
+ {
+ RunImpl(action.Method);
+ }
private static void Run<T>(Action<T> action, T arg)
- {
- RunImpl(action.Method, arg);
- }
-
- private static void Run<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
- {
- RunImpl(action.Method, arg1, arg2);
- }
+ {
+ RunImpl(action.Method, arg);
+ }
+
+ private static void Run<T1, T2>(Action<T1, T2> action, T1 arg1, T2
arg2)
+ {
+ RunImpl(action.Method, arg1, arg2);
+ }
private static void Run<T1, T2, T3>(Action<T1, T2, T3> action, T1
arg1, T2 arg2, T3 arg3)
{
RunImpl(action.Method, arg1, arg2, arg3);
}
- /// <summary>
- /// Take the passed action, run it, and then check that the last
method
- /// and last args are the same for pri and sec.
- /// </summary>
- private static void RunImpl(MethodBase action, params object[] args)
- {
+ /// <summary>
+ /// Take the passed action, run it, and then check that the last
method
+ /// and last args are the same for pri and sec.
+ /// </summary>
+ private static void RunImpl(MethodBase action, params object[]
args)
+ {
var recordings = new
Queue<CallRecording<ISelectorGenerator>>(2);
- primary.Recorder = recordings.Enqueue;
- secondary.Recorder = recordings.Enqueue;
-
- action.Invoke(tee, args);
-
- // Assert the fact that the primary and secondary methods were
- // both called with the same arguments and in the right order!
-
- var recording = recordings.Dequeue();
- Assert.AreSame(primary, recording.Target);
- Assert.AreEqual(action.Name,
MapMethod<ISelectorGenerator>(recording.Method).Name);
- Assert.AreEqual(args, recording.Arguments);
-
- recording = recordings.Dequeue();
- Assert.AreSame(secondary, recording.Target);
- Assert.AreEqual(action.Name,
MapMethod<ISelectorGenerator>(recording.Method).Name);
- Assert.AreEqual(args, recording.Arguments);
- }
-
- private static MethodInfo MapMethod<T>(MethodInfo method) where T :
class
- {
- var mapping = method.ReflectedType.GetInterfaceMap(typeof(T));
- return mapping.InterfaceMethods
- .Select((m, i) => new { Source = m, Target =
mapping.TargetMethods[i] })
- .Single(m => m.Target == method).Source;
- }
-
- private sealed class CallRecording<T>
- {
- public T Target { get; private set; }
- public MethodInfo Method { get; private set; }
- public object[] Arguments { get; private set; }
-
- public CallRecording(T target, MethodInfo method, object[]
arguments)
- {
- Target = target;
- Method = method;
- Arguments = arguments;
- }
- }
-
- private sealed class FakeSelectorGenerator : ISelectorGenerator
- {
+ primary.Recorder = recordings.Enqueue;
+ secondary.Recorder = recordings.Enqueue;
+
+ action.Invoke(tee, args);
+
+ // Assert the fact that the primary and secondary methods were
+ // both called with the same arguments and in the right order!
+
+ var recording = recordings.Dequeue();
+ Assert.AreSame(primary, recording.Target);
+ Assert.AreEqual(action.Name,
MapMethod<ISelectorGenerator>(recording.Method).Name);
+ Assert.AreEqual(args, recording.Arguments);
+
+ recording = recordings.Dequeue();
+ Assert.AreSame(secondary, recording.Target);
+ Assert.AreEqual(action.Name,
MapMethod<ISelectorGenerator>(recording.Method).Name);
+ Assert.AreEqual(args, recording.Arguments);
+ }
+
+ private static MethodInfo MapMethod<T>(MethodInfo method) where
T : class
+ {
+ var mapping = method.ReflectedType.GetInterfaceMap(typeof(T));
+ return mapping.InterfaceMethods
+ .Select((m, i) => new { Source = m, Target =
mapping.TargetMethods[i] })
+ .Single(m => m.Target == method).Source;
+ }
+
+ private sealed class CallRecording<T>
+ {
+ public T Target { get; private set; }
+ public MethodInfo Method { get; private set; }
+ public object[] Arguments { get; private set; }
+
+ public CallRecording(T target, MethodInfo method, object[]
arguments)
+ {
+ Target = target;
+ Method = method;
+ Arguments = arguments;
+ }
+ }
+
+ private sealed class FakeSelectorGenerator : ISelectorGenerator
+ {
public Action<CallRecording<ISelectorGenerator>> Recorder;
- public void OnInit()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void OnClose()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void OnSelector()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void Type(NamespacePrefix prefix, string type)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, type);
- }
-
- public void Universal(NamespacePrefix prefix)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix);
- }
-
- public void Id(string id)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), id);
- }
-
- public void Class(string clazz)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), clazz);
- }
-
- public void AttributeExists(NamespacePrefix prefix, string name)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, name);
- }
-
- public void AttributeExact(NamespacePrefix prefix, string name,
string value)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, name, value);
- }
-
- public void AttributeIncludes(NamespacePrefix prefix, string
name, string value)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, name, value);
- }
-
- public void AttributeDashMatch(NamespacePrefix prefix, string
name, string value)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, name, value);
- }
-
- public void AttributePrefixMatch(NamespacePrefix prefix, string
name, string value)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, name, value);
- }
-
- public void AttributeSuffixMatch(NamespacePrefix prefix, string
name, string value)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, name, value);
- }
-
- public void AttributeSubstring(NamespacePrefix prefix, string
name, string value)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), prefix, name, value);
- }
-
- public void FirstChild()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void LastChild()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void NthChild(int a, int b)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), a,b);
- }
-
- public void OnlyChild()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void Empty()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void Child()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void Descendant()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void Adjacent()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void GeneralSibling()
- {
- OnInvoked(MethodBase.GetCurrentMethod());
- }
-
- public void NthLastChild(int a, int b)
- {
- OnInvoked(MethodBase.GetCurrentMethod(), a, b);
- }
-
- private void OnInvoked(MethodBase method, params object[] args)
- {
- Recorder(new CallRecording<ISelectorGenerator>(this,
(MethodInfo) method, args));
- }
- }
- }
-}
+ public void OnInit()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void OnClose()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void OnSelector()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Type(NamespacePrefix prefix, string type)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, type);
+ }
+
+ public void Universal(NamespacePrefix prefix)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix);
+ }
+
+ public void Id(string id)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), id);
+ }
+
+ public void Class(string clazz)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), clazz);
+ }
+
+ public void AttributeExists(NamespacePrefix prefix, string
name)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name);
+ }
+
+ public void AttributeExact(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeIncludes(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeDashMatch(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributePrefixMatch(NamespacePrefix prefix,
string name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeSuffixMatch(NamespacePrefix prefix,
string name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeSubstring(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void FirstChild()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void LastChild()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void NthChild(int a, int b)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), a, b);
+ }
+
+ public void OnlyChild()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Empty()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Child()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Descendant()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Adjacent()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void GeneralSibling()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void NthLastChild(int a, int b)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), a, b);
+ }
+
+ private void OnInvoked(MethodBase method, params object[] args)
+ {
+ Recorder(new CallRecording<ISelectorGenerator>(this,
(MethodInfo) method, args));
+ }
+ }
+ }
+}