Permalink
Browse files

Added more ContentDirectory query support and tests.

  • Loading branch information...
1 parent 7fd9a9f commit ea0638c85a00d70d5df54a341ce9534d81885701 @lunchtimemama lunchtimemama committed Jul 23, 2010
View
4 HACKING
@@ -55,11 +55,11 @@ C# Style Guidelines
5. Private fileds and local variables look_like_this:
- string all_lower_case_with_underscores = null;
+ string all_lower_case_with_underscores = null; // Snake casing
Method parameters lookLikeThis:
- public void Foo (string lowerCaseAndThenUpperCase) // Camal casing
+ public void Foo (string lowerCaseAndThenUpperCase) // Camal casing
{
}
View
13 ...Dcp.MediaServer1/Mono.Upnp.Dcp.MediaServer1.ContentDirectory1/ObjectBasedQueryProvider.cs
@@ -33,7 +33,7 @@ public class ObjectBasedQueryProvider
{
Dictionary<Type, ObjectQueryContext> queryContexts = new Dictionary<Type, ObjectQueryContext>();
- public IEnumerable<Object> Query (Query query, IEnumerable<Object> objects)
+ public void Query (Query query, IEnumerable<Object> objects, Action<Object> consumer)
{
if (query == null) {
throw new ArgumentNullException ("query");
@@ -42,19 +42,10 @@ public IEnumerable<Object> Query (Query query, IEnumerable<Object> objects)
}
foreach (var @object in objects) {
- if (Matches (query, @object)) {
- yield return @object;
- }
+ query (new ObjectQueryVisitor (GetQueryContext (@object.GetType ()), @object, consumer));
}
}
- bool Matches (Query query, Object @object)
- {
- var match = false;
- query (new ObjectQueryVisitor (GetQueryContext (@object.GetType ()), @object, result => match = result));
- return match;
- }
-
ObjectQueryContext GetQueryContext (Type type)
{
if (type == null) {
View
31 ....Upnp.Dcp.MediaServer1/Mono.Upnp.Dcp.MediaServer1.ContentDirectory1/ObjectQueryContext.cs
@@ -52,6 +52,7 @@ public ObjectQueryContext (Type type, ObjectQueryContext parentContext)
}
this.parentContext = parentContext;
+
foreach (var property_info in GetProperties (type, BindingFlags.DeclaredOnly)) {
foreach (var attribute in property_info.GetCustomAttributes (false)) {
if (ProcessElementAttribute (property_info, attribute as XmlElementAttribute)) {
@@ -121,16 +122,33 @@ void ProcessNestedAttributes (string nestedName, PropertyVisitor parentProperty)
}
}
- public void VisitProperty<T> (string property, object @object, Action<T> consumer)
+ public void VisitProperty (string property, object @object, Action<object> consumer)
{
PropertyVisitor property_visitor;
if (properties.TryGetValue (property, out property_visitor)) {
- property_visitor.Visit (@object, value => consumer ((T)value));
+ property_visitor.Visit (@object, value => consumer (value));
} else if (parentContext != null) {
parentContext.VisitProperty (property, @object, consumer);
}
}
+ public void CompareProperty (string property, object @object, string value, Action<int> consumer)
+ {
+ PropertyVisitor property_visitor;
+ if (properties.TryGetValue (property, out property_visitor)) {
+ property_visitor.Visit (@object, val => {
+ if (property_visitor.ParseMethod != null) {
+ var parsed_value = property_visitor.ParseMethod.Invoke (null, new[] { value });
+ consumer (((IComparable)val).CompareTo (parsed_value));
+ } else {
+ // TODO throw?
+ }
+ });
+ } else if (parentContext != null) {
+ parentContext.CompareProperty (property, @object, value, consumer);
+ }
+ }
+
public bool PropertyExists (string property, object @object)
{
PropertyVisitor property_visitor;
@@ -157,10 +175,19 @@ static IEnumerable<PropertyInfo> GetProperties (Type type, BindingFlags flags)
abstract class PropertyVisitor
{
public readonly PropertyInfo PropertyInfo;
+ public readonly MethodInfo ParseMethod;
protected PropertyVisitor (PropertyInfo propertyInfo)
{
this.PropertyInfo = propertyInfo;
+ var property_type = propertyInfo.PropertyType;
+ if (property_type.IsGenericType && property_type.GetGenericTypeDefinition () == typeof (Nullable<>)) {
+ property_type = property_type.GetGenericArguments ()[0];
+ }
+ if (typeof (IComparable).IsAssignableFrom (property_type)) {
+ this.ParseMethod = property_type.GetMethod (
+ "Parse", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof (string) }, null);
+ }
}
public abstract void Visit (object @object, Action<object> consumer);
View
106 ....Upnp.Dcp.MediaServer1/Mono.Upnp.Dcp.MediaServer1.ContentDirectory1/ObjectQueryVisitor.cs
@@ -34,9 +34,9 @@ public class ObjectQueryVisitor : QueryVisitor
{
readonly ObjectQueryContext context;
readonly Object @object;
- readonly Action<bool> consumer;
+ readonly Action<Object> consumer;
- public ObjectQueryVisitor (ObjectQueryContext context, Object @object, Action<bool> consumer)
+ public ObjectQueryVisitor (ObjectQueryContext context, Object @object, Action<Object> consumer)
{
if (context == null) {
throw new ArgumentNullException ("context");
@@ -52,58 +52,110 @@ public ObjectQueryVisitor (ObjectQueryContext context, Object @object, Action<bo
public override void VisitAllResults ()
{
- consumer (true);
+ consumer (@object);
}
public override void VisitAnd (Query leftOperand, Query rightOperand)
{
- Visit (leftOperand, leftResult => {
- if (leftResult) {
- Visit (rightOperand, rightResult => consumer (rightResult));
- } else {
- consumer (false);
- }
- });
+ leftOperand (new ObjectQueryVisitor (context, @object, result => rightOperand (this)));
}
public override void VisitOr (Query leftOperand, Query rightOperand)
{
- Visit (leftOperand, leftResult => {
- if (leftResult) {
- consumer (true);
- } else {
- Visit (rightOperand, rightResult => consumer (rightResult));
- }
- });
+ Object leftResult = null;
+ leftOperand (new ObjectQueryVisitor (context, @object, result => leftResult = result));
+ if (leftResult == null) {
+ rightOperand (this);
+ } else {
+ consumer (leftResult);
+ }
+ }
+
+ public override void VisitExists (string property, bool value)
+ {
+ if (context.PropertyExists (property, @object) == value) {
+ consumer (@object);
+ }
}
public override void VisitEquals (string property, string value)
{
- context.VisitProperty <object> (property, @object, v => {
- if (v == null) {
+ context.VisitProperty (property, @object, val => {
+ if (val == null) {
if (value == null) {
- consumer (true);
+ consumer (@object);
}
- } else if (v.ToString ().Equals (value)) {
- consumer (true);
+ } else if (val.ToString ().Equals (value)) {
+ consumer (@object);
}
});
}
public override void VisitDoesNotEqual (string property, string value)
{
- //VisitPropertyExpression<object> (property, val => consumer (!val.Equals (value)));
+ context.VisitProperty (property, @object, val => {
+ if (val == null) {
+ if (value != null) {
+ consumer (@object);
+ }
+ } else if (!val.ToString ().Equals (value)) {
+ consumer (@object);
+ }
+ });
+ }
+
+ public override void VisitLessThan (string property, string value)
+ {
+ context.CompareProperty (property, @object, value, val => {
+ if (val < 0) {
+ consumer (@object);
+ }
+ });
+ }
+
+ public override void VisitLessThanOrEqualTo (string property, string value)
+ {
+ context.CompareProperty (property, @object, value, val => {
+ if (val <= 0) {
+ consumer (@object);
+ }
+ });
+ }
+
+ public override void VisitGreaterThan (string property, string value)
+ {
+ context.CompareProperty (property, @object, value, val => {
+ if (val > 0) {
+ consumer (@object);
+ }
+ });
+ }
+
+ public override void VisitGreaterThanOrEqualTo (string property, string value)
+ {
+ context.CompareProperty (property, @object, value, val => {
+ if (val >= 0) {
+ consumer (@object);
+ }
+ });
}
public override void VisitContains (string property, string value)
{
- //VisitPropertyExpression<string> (property, val => consumer (val.Contains (value)));
+ context.VisitProperty (property, @object, val => {
+ if (val != null && val.ToString ().Contains (value)) {
+ consumer (@object);
+ }
+ });
}
- void Visit (Query query, Action<bool> consumer)
+ public override void VisitDoesNotContain (string property, string value)
{
- query (new ObjectQueryVisitor (context, @object, consumer));
+ context.VisitProperty (property, @object, val => {
+ if (val == null || !val.ToString ().Contains (value)) {
+ consumer (@object);
+ }
+ });
}
}
}
-
View
2 tests/Mono.Upnp.Dcp.MediaServer1.Tests/FilteringXmlSerializerTests.cs
@@ -45,8 +45,8 @@ public class FilteringXmlSerializerTests
const string bat = "www.bat.org";
[XmlType ("data", foo)]
- [XmlNamespace (bar, "bar")]
[XmlNamespace (bat, "bat")]
+ [XmlNamespace (bar, "bar")]
class Data
{
[XmlElement ("manditoryFooElement", foo)] public string ManditoryFooElement { get; set; }
View
2 tests/Mono.Upnp.Dcp.MediaServer1.Tests/Mono.Upnp.Dcp.MediaServer1.Tests.csproj
@@ -60,6 +60,8 @@
<Compile Include="ObjectQueryTests.cs" />
<Compile Include="DummyObject.cs" />
<Compile Include="DummyContentDirectory.cs" />
+ <Compile Include="Property.cs" />
+ <Compile Include="QueryTests.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
View
40 tests/Mono.Upnp.Dcp.MediaServer1.Tests/ObjectQueryContextTests.cs
@@ -53,10 +53,10 @@ public void Element ()
Assert.IsTrue (context.PropertyExists ("Foo", foo));
Assert.IsFalse (context.PropertyExists ("Bar", foo));
var equality = false;
- context.VisitProperty<string> ("Foo", foo, value => equality = value == "bar");
+ context.VisitProperty ("Foo", foo, value => equality = value.Equals ("bar"));
Assert.IsTrue (equality);
equality = false;
- context.VisitProperty<string> ("Foo", new ElementTestClass (), value => equality = value == null);
+ context.VisitProperty ("Foo", new ElementTestClass (), value => equality = value == null);
Assert.IsTrue (equality);
}
@@ -111,10 +111,10 @@ public void Attribute ()
Assert.IsTrue (context.PropertyExists ("@Foo", foo));
Assert.IsFalse (context.PropertyExists ("@Bar", foo));
var equality = false;
- context.VisitProperty<string> ("@Foo", foo, value => equality = value == "bar");
+ context.VisitProperty ("@Foo", foo, value => equality = value.Equals ("bar"));
Assert.IsTrue (equality);
equality = false;
- context.VisitProperty<string> ("@Foo", new AttributeTestClass (), value => equality = value == null);
+ context.VisitProperty ("@Foo", new AttributeTestClass (), value => equality = value == null);
Assert.IsTrue (equality);
}
@@ -195,7 +195,7 @@ public void NestedElements ()
Assert.IsTrue (context.PropertyExists ("OmitIfNullAttribute@Foo", test));
var equality = false;
- context.VisitProperty<string> ("OmitIfNullAttribute@Foo", test, value => equality = value == "bar");
+ context.VisitProperty ("OmitIfNullAttribute@Foo", test, value => equality = value.Equals ("bar"));
Assert.IsTrue (equality);
}
@@ -215,7 +215,7 @@ public void ArrayItem ()
Assert.IsTrue (context.PropertyExists ("Foo", test));
var i = 0;
var inequality = false;
- context.VisitProperty<string> ("Foo", test, value => inequality |= value != foos[i++]);
+ context.VisitProperty ("Foo", test, value => inequality |= !value.Equals (foos[i++]));
Assert.IsFalse (inequality);
}
@@ -262,7 +262,7 @@ public void NestedArrayTestClass ()
var test = new NestedArrayItemTestClass { Foo = foos };
var i = 0;
var inequality = false;
- context.VisitProperty<string>("Foo@Foo", test, value => inequality |= value != attributes[i++]);
+ context.VisitProperty ("Foo@Foo", test, value => inequality |= !value.Equals (attributes[i++]));
Assert.IsFalse (inequality);
}
@@ -283,5 +283,31 @@ public void SuperclassLookup ()
Assert.IsTrue (subclass_context.PropertyExists ("Bar", test));
Assert.IsFalse (new ObjectQueryContext (typeof (ElementTestSubclass)).PropertyExists ("Foo", test));
}
+
+ class NullableElementTestClass
+ {
+ [XmlElement (OmitIfNull = true)] public int? Foo { get; set; }
+ }
+
+ [Test]
+ public void NullableElement ()
+ {
+ var context = new ObjectQueryContext (typeof (NullableElementTestClass));
+ Assert.IsTrue (context.PropertyExists ("Foo", new NullableElementTestClass { Foo = 42 }));
+ Assert.IsFalse (context.PropertyExists ("Foo", new NullableElementTestClass ()));
+ }
+
+ class NullableAttributeTestClass
+ {
+ [XmlAttribute (OmitIfNull = true)] public int? Foo { get; set; }
+ }
+
+ [Test]
+ public void NullableAttribute ()
+ {
+ var context = new ObjectQueryContext (typeof (NullableAttributeTestClass));
+ Assert.IsTrue (context.PropertyExists ("@Foo", new NullableAttributeTestClass { Foo = 42 }));
+ Assert.IsFalse (context.PropertyExists ("@Foo", new NullableAttributeTestClass ()));
+ }
}
}
View
177 tests/Mono.Upnp.Dcp.MediaServer1.Tests/ObjectQueryTests.cs
@@ -25,6 +25,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using NUnit.Framework;
@@ -34,24 +35,182 @@
namespace Mono.Upnp.Dcp.MediaServer1.Tests
{
[TestFixture]
- public class ObjectQueryTests
+ public class ObjectQueryTests : QueryTests
{
+ readonly Property text = new Property ("Text");
+ readonly Property number = new Property ("Number");
+ readonly Property nullable_number = new Property ("NullableNumber");
+
class Data : DummyObject
{
- [XmlElement] public string Foo { get; set; }
+ [XmlElement] public string Text { get; set; }
+ [XmlElement] public int Number { get; set; }
+ [XmlElement] public int? NullableNumber { get; set; }
+ }
+
+ Data FullData {
+ get { return new Data { Text = "bar", Number = 42, NullableNumber = 13 }; }
}
[Test]
public void Equality ()
{
- var data = new Data { Foo = "bar" };
+ Assert.IsTrue (Matches (FullData, text == "bar"));
+ Assert.IsFalse (Matches (FullData, text == null));
+ Assert.IsFalse (Matches (FullData, text == "bat"));
+ Assert.IsTrue (Matches (new Data (), text == null));
+ Assert.IsTrue (Matches (FullData, number == "42"));
+ Assert.IsFalse (Matches (FullData, number == "13"));
+ Assert.IsTrue (Matches (FullData, nullable_number == "13"));
+ Assert.IsTrue (Matches (new Data (), nullable_number == null));
+ Assert.IsFalse (Matches (FullData, nullable_number == null));
+ }
+
+ [Test]
+ public void Inequality ()
+ {
+ Assert.IsTrue (Matches (FullData, text != "bat"));
+ Assert.IsTrue (Matches (FullData, text != null));
+ Assert.IsFalse (Matches (FullData, text != "bar"));
+ Assert.IsFalse (Matches (new Data (), text != null));
+ Assert.IsTrue (Matches (FullData, number != "13"));
+ Assert.IsFalse (Matches (FullData, number != "42"));
+ Assert.IsFalse (Matches (new Data (), nullable_number != null));
+ Assert.IsTrue (Matches (FullData, nullable_number != null));
+ }
+
+ [Test]
+ public void LessThan ()
+ {
+ Assert.IsTrue (Matches (FullData, number < "43"));
+ Assert.IsFalse (Matches (FullData, number < "42"));
+ Assert.IsTrue (Matches (FullData, nullable_number < "14"));
+ Assert.IsFalse (Matches (FullData, nullable_number < "13"));
+ }
+
+ [Test]
+ public void LessThanOrEqualTo ()
+ {
+ Assert.IsTrue (Matches (FullData, number <= "43"));
+ Assert.IsTrue (Matches (FullData, number <= "42"));
+ Assert.IsFalse (Matches (FullData, number <= "41"));
+ Assert.IsTrue (Matches (FullData, nullable_number <= "14"));
+ Assert.IsTrue (Matches (FullData, nullable_number <= "13"));
+ Assert.IsFalse (Matches (FullData, nullable_number <= "12"));
+ }
+
+ [Test]
+ public void GreaterThan ()
+ {
+ Assert.IsTrue (Matches (FullData, number > "41"));
+ Assert.IsFalse (Matches (FullData, number > "42"));
+ Assert.IsTrue (Matches (FullData, nullable_number > "12"));
+ Assert.IsFalse (Matches (FullData, nullable_number > "13"));
+ }
+
+ [Test]
+ public void GreaterThanOrEqualTo ()
+ {
+ Assert.IsTrue (Matches (FullData, number >= "41"));
+ Assert.IsTrue (Matches (FullData, number >= "42"));
+ Assert.IsFalse (Matches (FullData, number >= "43"));
+ Assert.IsTrue (Matches (FullData, nullable_number >= "12"));
+ Assert.IsTrue (Matches (FullData, nullable_number >= "13"));
+ Assert.IsFalse (Matches (FullData, nullable_number >= "14"));
+ }
+
+ [Test]
+ public void Contains ()
+ {
+ Assert.IsTrue (Matches (FullData, text.Contains ("bar")));
+ Assert.IsTrue (Matches (FullData, text.Contains ("ba")));
+ Assert.IsTrue (Matches (FullData, text.Contains ("ar")));
+ Assert.IsFalse (Matches (FullData, text.Contains ("bart")));
+ Assert.IsFalse (Matches (FullData, text.Contains ("bb")));
+ Assert.IsFalse (Matches (new Data (), text.Contains ("bb")));
+ }
+
+ [Test]
+ public void DoesNotContain ()
+ {
+ Assert.IsFalse (Matches (FullData, text.DoesNotContain ("bar")));
+ Assert.IsFalse (Matches (FullData, text.DoesNotContain ("ba")));
+ Assert.IsFalse (Matches (FullData, text.DoesNotContain ("ar")));
+ Assert.IsTrue (Matches (FullData, text.DoesNotContain ("bart")));
+ Assert.IsTrue (Matches (FullData, text.DoesNotContain ("bb")));
+ Assert.IsTrue (Matches (new Data (), text.DoesNotContain ("bb")));
+ }
+
+ [Test]
+ public void Conjoin ()
+ {
+ Assert.IsTrue (Matches (FullData, Conjoin (text == "bar", number == "42")));
+ Assert.IsTrue (Matches (
+ FullData, Conjoin (Conjoin (text == "bar", number == "42"), nullable_number <= "13")));
+ Assert.IsFalse (Matches (FullData, Conjoin (text == "bar", number < "42")));
+ Assert.IsFalse (Matches (FullData, Conjoin (text == "bart", number == "42")));
+ }
+
+ [Test]
+ public void Disjoin ()
+ {
+ Assert.IsTrue (Matches (FullData, Disjoin (text == "bar", number == "42")));
+ Assert.IsTrue (Matches (FullData, Disjoin (text == "bar", number < "42")));
+ Assert.IsTrue (Matches (FullData, Disjoin (text == "bart", number == "42")));
+ Assert.IsTrue (Matches (
+ FullData, Disjoin (Disjoin (text == "bart", number == "42"), nullable_number == "13")));
+ Assert.IsTrue (Matches (
+ FullData, Disjoin (Disjoin (text == "bart", number != "42"), nullable_number == "13")));
+ Assert.IsFalse (Matches (FullData, Disjoin (text == "bart", number < "42")));
+ }
+
+ class OmitIfNullData : DummyObject
+ {
+ [XmlElement (OmitIfNull = true)] public string Text { get; set; }
+ [XmlElement (OmitIfNull = true)] public int? Number { get; set; }
+ }
+
+ [Test]
+ public void Exists ()
+ {
+ var data = new OmitIfNullData { Text = "foo", Number = 42 };
+ Assert.IsTrue (Matches (data, text.Exists (true)));
+ Assert.IsFalse (Matches (data, text.Exists (false)));
+ Assert.IsTrue (Matches (data, number.Exists (true)));
+ Assert.IsFalse (Matches (data, number.Exists (false)));
+ Assert.IsFalse (Matches (new OmitIfNullData (), text.Exists (true)));
+ Assert.IsTrue (Matches (new OmitIfNullData (), text.Exists (false)));
+ Assert.IsFalse (Matches (new OmitIfNullData (), number.Exists (true)));
+ Assert.IsTrue (Matches (new OmitIfNullData (), number.Exists (false)));
+ }
+
+ class ArrayItemData : DummyObject
+ {
+ [XmlArrayItem] public IEnumerable<string> Text { get; set; }
+ }
+
+ [Test]
+ public void ArrayItemDataTest ()
+ {
+ var data = new ArrayItemData { Text = new[] { "one", "two", "three" } };
+ Assert.IsTrue (Matches (data, text == "two"));
+ Assert.IsTrue (Matches (data, text.Contains ("ee")));
+ Assert.IsTrue (Matches (data, text.Exists (true)));
+ Assert.IsFalse (Matches (data, text.Exists (false)));
+ Assert.IsTrue (Matches (new ArrayItemData (), text.Exists (false)));
+ Assert.IsFalse (Matches (new ArrayItemData (), text.Exists (true)));
+ }
+
+ static bool Matches (Mono.Upnp.Dcp.MediaServer1.ContentDirectory1.Object @object, Query query)
+ {
var match = false;
- var visitor = new ObjectQueryVisitor (new ObjectQueryContext (typeof (Data)), data, result => match = result);
- visitor.VisitEquals ("Foo", "bar");
- Assert.IsTrue (match);
- match = false;
- visitor.VisitEquals ("Foo", "bat");
- Assert.IsFalse (match);
+ query (new ObjectQueryVisitor (new ObjectQueryContext (@object.GetType ()), @object, result => {
+ if (match) {
+ Assert.Fail ("Multiple matches for a single input.");
+ }
+ match = result == @object;
+ }));
+ return match;
}
}
}
View
93 tests/Mono.Upnp.Dcp.MediaServer1.Tests/Property.cs
@@ -0,0 +1,93 @@
+//
+// Property.cs
+//
+// Author:
+// Scott Thomas <lunchtimemama@gmail.com>
+//
+// Copyright (c) 2010 Scott Thomas
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using Mono.Upnp.Dcp.MediaServer1.ContentDirectory1;
+
+namespace Mono.Upnp.Dcp.MediaServer1.Tests
+{
+ #pragma warning disable 0660, 0661
+ public class Property
+ {
+ readonly string name;
+
+ public Property (string name)
+ {
+ this.name = name;
+ }
+
+ public Query Contains (string value)
+ {
+ return visitor => visitor.VisitContains (name, value);
+ }
+
+ public Query DoesNotContain (string value)
+ {
+ return visitor => visitor.VisitDoesNotContain (name, value);
+ }
+
+ public Query DerivedFrom (string value)
+ {
+ return visitor => visitor.VisitDerivedFrom (name, value);
+ }
+
+ public Query Exists (bool value)
+ {
+ return visitor => visitor.VisitExists (name, value);
+ }
+
+ public static Query operator ==(Property property, string value)
+ {
+ return visitor => visitor.VisitEquals (property.name, value);
+ }
+
+ public static Query operator !=(Property property, string value)
+ {
+ return visitor => visitor.VisitDoesNotEqual (property.name, value);
+ }
+
+ public static Query operator <(Property property, string value)
+ {
+ return visitor => visitor.VisitLessThan (property.name, value);
+ }
+
+ public static Query operator <=(Property property, string value)
+ {
+ return visitor => visitor.VisitLessThanOrEqualTo (property.name, value);
+ }
+
+ public static Query operator >(Property property, string value)
+ {
+ return visitor => visitor.VisitGreaterThan (property.name, value);
+ }
+
+ public static Query operator >=(Property property, string value)
+ {
+ return visitor => visitor.VisitGreaterThanOrEqualTo (property.name, value);
+ }
+ }
+ #pragma warning restore 0661, 0660
+}
+
View
156 tests/Mono.Upnp.Dcp.MediaServer1.Tests/QueryParserTests.cs
@@ -34,195 +34,129 @@
namespace Mono.Upnp.Dcp.MediaServer1.Tests
{
[TestFixture]
- public class QueryParserTests
+ public class QueryParserTests : QueryTests
{
- #pragma warning disable 0660, 0661
- class Property
- {
- string name;
-
- public Property (string name)
- {
- this.name = name;
- }
-
- public Query Contains (string value)
- {
- return visitor => visitor.VisitContains (name, value);
- }
-
- public Query DoesNotContain (string value)
- {
- return visitor => visitor.VisitDoesNotContain (name, value);
- }
-
- public Query DerivedFrom (string value)
- {
- return visitor => visitor.VisitDerivedFrom (name, value);
- }
-
- public Query Exists (bool value)
- {
- return visitor => visitor.VisitExists (name, value);
- }
-
- public static Query operator ==(Property property, string value)
- {
- return visitor => visitor.VisitEquals (property.name, value);
- }
-
- public static Query operator !=(Property property, string value)
- {
- return visitor => visitor.VisitDoesNotEqual (property.name, value);
- }
-
- public static Query operator <(Property property, string value)
- {
- return visitor => visitor.VisitLessThan (property.name, value);
- }
-
- public static Query operator <=(Property property, string value)
- {
- return visitor => visitor.VisitLessThanOrEqualTo (property.name, value);
- }
-
- public static Query operator >(Property property, string value)
- {
- return visitor => visitor.VisitGreaterThan (property.name, value);
- }
-
- public static Query operator >=(Property property, string value)
- {
- return visitor => visitor.VisitGreaterThanOrEqualTo (property.name, value);
- }
- }
- #pragma warning restore 0661, 0660
-
- static Query Conjoin (Query leftOperand, Query rightOperand)
- {
- return visitor => visitor.VisitAnd (leftOperand, rightOperand);
- }
-
- static Query Disjoin (Query leftOperand, Query rightOperand)
- {
- return visitor => visitor.VisitOr (leftOperand, rightOperand);
- }
+ readonly Property foo = new Property ("foo");
+ readonly Property bat = new Property ("bat");
+ readonly Property name = new Property ("name");
+ readonly Property eyes = new Property ("eyes");
+ readonly Property age = new Property ("age");
[Test]
public void EqualityOperator ()
{
- AssertEquality (new Property ("foo") == "bar", @"foo = ""bar""");
+ AssertEquality (foo == "bar", @"foo = ""bar""");
}
[Test]
public void InequalityOperator ()
{
- AssertEquality (new Property ("foo") != "bar", @"foo != ""bar""");
+ AssertEquality (foo != "bar", @"foo != ""bar""");
}
[Test]
public void LessThanOperator ()
{
- AssertEquality (new Property ("foo") < "5", @"foo < ""5""");
+ AssertEquality (foo < "5", @"foo < ""5""");
}
[Test]
public void LessThanOrEqualOperator ()
{
- AssertEquality (new Property ("foo") <= "5", @"foo <= ""5""");
+ AssertEquality (foo <= "5", @"foo <= ""5""");
}
[Test]
public void GreaterThanOperator ()
{
- AssertEquality (new Property ("foo") > "5", @"foo > ""5""");
+ AssertEquality (foo > "5", @"foo > ""5""");
}
[Test]
public void GreaterThanOrEqualOperator ()
{
- AssertEquality (new Property ("foo") >= "5", @"foo >= ""5""");
+ AssertEquality (foo >= "5", @"foo >= ""5""");
}
[Test]
public void ContainsOperator ()
{
- AssertEquality (new Property ("foo").Contains ("bar"), @"foo contains ""bar""");
+ AssertEquality (foo.Contains ("bar"), @"foo contains ""bar""");
}
[Test]
public void ExistsTrue ()
{
- AssertEquality (new Property ("foo").Exists (true), "foo exists true");
+ AssertEquality (foo.Exists (true), "foo exists true");
}
[Test]
public void ExistsFalse ()
{
- AssertEquality (new Property ("foo").Exists (false), "foo exists false");
+ AssertEquality (foo.Exists (false), "foo exists false");
}
[Test]
public void ExistsTrueWithTrailingWhiteSpace ()
{
- AssertEquality (new Property ("foo").Exists (true), "foo exists true ");
+ AssertEquality (foo.Exists (true), "foo exists true ");
}
[Test]
public void ExistsFalseWithTrailingWhiteSpace ()
{
- AssertEquality (new Property ("foo").Exists (false), "foo exists false ");
+ AssertEquality (foo.Exists (false), "foo exists false ");
}
[Test]
public void ExistsTrueWithLeadingWhiteSpace ()
{
- AssertEquality (new Property ("foo").Exists (true), "foo exists \t\rtrue");
+ AssertEquality (foo.Exists (true), "foo exists \t\rtrue");
}
[Test]
public void ExistsFalseWithLeadingWhiteSpace ()
{
- AssertEquality (new Property ("foo").Exists (false), "foo exists \t\rfalse");
+ AssertEquality (foo.Exists (false), "foo exists \t\rfalse");
}
[Test]
public void DerivedFromOperator ()
{
- AssertEquality (new Property ("foo").DerivedFrom ("object.item"), @"foo derivedFrom ""object.item""");
+ AssertEquality (foo.DerivedFrom ("object.item"), @"foo derivedFrom ""object.item""");
}
[Test]
public void DoesNotContainOperator ()
{
- AssertEquality (new Property ("foo").DoesNotContain ("bar"), @"foo doesNotContain ""bar""");
+ AssertEquality (foo.DoesNotContain ("bar"), @"foo doesNotContain ""bar""");
}
[Test]
public void EscapedDoubleQuote ()
{
- AssertEquality (new Property ("foo") == @"b""a""r", @"foo = ""b\""a\""r""");
+ AssertEquality (foo == @"b""a""r", @"foo = ""b\""a\""r""");
}
[Test]
public void EscapedSlash ()
{
- AssertEquality (new Property ("foo") == @"b\a\r", @"foo = ""b\\a\\r""");
+ AssertEquality (foo == @"b\a\r", @"foo = ""b\\a\\r""");
}
[Test]
public void AndOperator ()
{
AssertEquality (
- Conjoin (new Property ("foo") == "bar", new Property ("bat") == "baz"),
+ Conjoin (foo == "bar", bat == "baz"),
@"foo = ""bar"" and bat = ""baz""");
}
[Test]
public void OrOperator ()
{
AssertEquality (
- Disjoin (new Property ("foo") == "bar", new Property ("bat") == "baz"),
+ Disjoin (foo == "bar", bat == "baz"),
@"foo = ""bar"" or bat = ""baz""");
}
@@ -232,9 +166,9 @@ public void OperatorPriority ()
AssertEquality (
Disjoin (
Disjoin (
- Conjoin (new Property ("foo") == "bar", new Property ("bat") == "baz"),
- new Property ("name").Contains ("john")),
- Conjoin (new Property ("eyes") == "green", new Property ("age") >= "21")),
+ Conjoin (foo == "bar", bat == "baz"),
+ name.Contains ("john")),
+ Conjoin (eyes == "green", age >= "21")),
@"foo = ""bar"" and bat = ""baz"" or name contains ""john"" or eyes = ""green"" and age >= ""21""");
}
@@ -243,10 +177,10 @@ public void ParentheticalPriority1 ()
{
AssertEquality (
Disjoin (
- Conjoin (new Property ("foo") == "bar", new Property ("bat") == "baz"),
+ Conjoin (foo == "bar", bat == "baz"),
Conjoin (
- Disjoin (new Property ("name").Contains ("john"), new Property ("eyes") == "green"),
- new Property ("age") >= "21")),
+ Disjoin (name.Contains ("john"), eyes == "green"),
+ age >= "21")),
@"foo = ""bar"" and bat = ""baz"" or (name contains ""john"" or eyes = ""green"") and age >= ""21""");
}
@@ -256,11 +190,11 @@ public void ParentheticalPriority2 ()
AssertEquality (
Conjoin (
Conjoin (
- new Property ("foo") == "bar",
+ foo == "bar",
Disjoin (
- Disjoin (new Property ("bat") == "baz", new Property ("name").Contains ("john")),
- new Property ("eyes") == "green")),
- new Property ("age") >= "21"),
+ Disjoin (bat == "baz", name.Contains ("john")),
+ eyes == "green")),
+ age >= "21"),
@"foo = ""bar"" and ((bat = ""baz"" or name contains ""john"") or eyes = ""green"") and age >= ""21""");
}
@@ -270,9 +204,9 @@ public void ParentheticalPriority3 ()
AssertEquality (
Disjoin (
Conjoin (
- new Property ("foo") == "bar",
- Disjoin (new Property ("bat") == "baz", new Property ("name").Contains ("john"))),
- Conjoin (new Property ("eyes") == "green", new Property ("age") >= "21")),
+ foo == "bar",
+ Disjoin (bat == "baz", name.Contains ("john"))),
+ Conjoin (eyes == "green", age >= "21")),
@"foo = ""bar"" and (bat = ""baz"" or name contains ""john"") or eyes = ""green"" and age >= ""21""");
}
@@ -282,9 +216,9 @@ public void ParentheticalPriority4 ()
AssertEquality (
Conjoin (
Conjoin (
- Disjoin (new Property ("foo") == "bar", new Property ("bat") == "baz"),
- Disjoin (new Property ("name").Contains ("john"), new Property ("eyes") == "green")),
- new Property ("age") >= "21"),
+ Disjoin (foo == "bar", bat == "baz"),
+ Disjoin (name.Contains ("john"), eyes == "green")),
+ age >= "21"),
@"(foo = ""bar"" or bat = ""baz"") and (name contains ""john"" or eyes = ""green"") and age >= ""21""");
}
@@ -293,10 +227,10 @@ public void ParentheticalPriority5 ()
{
AssertEquality (
Conjoin (
- Disjoin (new Property ("foo") == "bar", new Property ("bat").Exists (true)),
+ Disjoin (foo == "bar", bat.Exists (true)),
Conjoin (
- Disjoin (new Property ("name").Contains ("john"), new Property ("eyes").Exists (false)),
- new Property ("age") >= "21")),
+ Disjoin (name.Contains ("john"), eyes.Exists (false)),
+ age >= "21")),
@"(foo = ""bar"" or bat exists true) and ((name contains ""john"" or eyes exists false) and age >= ""21"")");
}
@@ -315,7 +249,7 @@ public void WildCardWithWhiteSpace ()
[Test]
public void WhiteSpaceAroundOperator ()
{
- var expected = new Property ("foo") == "bar";
+ var expected = foo == "bar";
AssertEquality (expected, @" foo = ""bar""");
AssertEquality (expected, @"foo = ""bar""");
AssertEquality (expected, @"foo = ""bar""");
View
2 tests/Mono.Upnp.Dcp.MediaServer1.Tests/QueryStringifier.cs
@@ -41,7 +41,7 @@ public QueryStringifier (StringBuilder builder)
public override void VisitEquals (string property, string value)
{
- VisitPropertyOperator (property, "==", value);
+ VisitPropertyOperator (property, "=", value);
}
public override void VisitDoesNotEqual (string property, string value)
View
44 tests/Mono.Upnp.Dcp.MediaServer1.Tests/QueryTests.cs
@@ -0,0 +1,44 @@
+//
+// QueryTests.cs
+//
+// Author:
+// Scott Thomas <lunchtimemama@gmail.com>
+//
+// Copyright (c) 2010 Scott Thomas
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using Mono.Upnp.Dcp.MediaServer1.ContentDirectory1;
+
+namespace Mono.Upnp.Dcp.MediaServer1.Tests
+{
+ public class QueryTests
+ {
+ protected static Query Conjoin (Query leftOperand, Query rightOperand)
+ {
+ return visitor => visitor.VisitAnd (leftOperand, rightOperand);
+ }
+
+ protected static Query Disjoin (Query leftOperand, Query rightOperand)
+ {
+ return visitor => visitor.VisitOr (leftOperand, rightOperand);
+ }
+ }
+}
+

0 comments on commit ea0638c

Please sign in to comment.