public void GetPathTwoLevelsGenerics()
        {
            var intActuals1  = PropertyPathParser.GetPath <Fake <int>, int>(x => x.Next.Value);
            var intExpecteds = new[] { typeof(Fake <int>).GetProperty(nameof(Fake <int> .Next), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), typeof(Level <int>).GetProperty(nameof(Level <int> .Value), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) };

            CollectionAssert.AreEqual(intExpecteds, intActuals1);

            var intActuals2 = PropertyPathParser.GetPath <Fake <int>, int>(x => x.Next.Value);

            Assert.AreSame(intActuals1, intActuals2);

            var intFake     = new Fake <int>();
            var intActuals3 = PropertyPathParser.GetPath(() => intFake.Next.Value);

            Assert.AreSame(intActuals1, intActuals3);

            var doubleActuals1  = PropertyPathParser.GetPath <Fake <double>, double>(x => x.Next.Value);
            var doubleExpecteds = new[] { typeof(Fake <double>).GetProperty(nameof(Fake <double> .Next), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), typeof(Level <double>).GetProperty(nameof(Level <double> .Value), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) };

            CollectionAssert.AreEqual(doubleExpecteds, doubleActuals1);

            var doubleActuals2 = PropertyPathParser.GetPath <Fake <double>, double>(x => x.Next.Value);

            Assert.AreSame(doubleActuals1, doubleActuals2);
            Assert.AreNotSame(intActuals1, doubleActuals2);

            var doubleFake     = new Fake <double>();
            var doubleActuals3 = PropertyPathParser.GetPath(() => doubleFake.Next.Value);

            Assert.AreSame(doubleActuals1, doubleActuals3);
            Assert.AreNotSame(intActuals1, doubleActuals2);
        }
Example #2
0
        public void Parse_ValidPath_IsParsedCorrect(string path)
        {
            var parser     = new PropertyPathParser();
            var parsedPath = parser.Parse(path);

            Assert.AreEqual(path, parsedPath.ToString());
        }
        public void GetPathTwoLevelsGenerics()
        {
            var intActuals1  = PropertyPathParser.GetPath <Fake <int>, int>(x => x.Next.Value);
            var intExpecteds = new[] { typeof(Fake <int>).GetProperty("Next"), typeof(Level <int>).GetProperty("Value") };

            CollectionAssert.AreEqual(intExpecteds, intActuals1);

            var intActuals2 = PropertyPathParser.GetPath <Fake <int>, int>(x => x.Next.Value);

            Assert.AreSame(intActuals1, intActuals2);

            var intFake     = new Fake <int>();
            var intActuals3 = PropertyPathParser.GetPath(() => intFake.Next.Value);

            Assert.AreSame(intActuals1, intActuals3);

            var doubleActuals1  = PropertyPathParser.GetPath <Fake <double>, double>(x => x.Next.Value);
            var doubleExpecteds = new[] { typeof(Fake <double>).GetProperty("Next"), typeof(Level <double>).GetProperty("Value") };

            CollectionAssert.AreEqual(doubleExpecteds, doubleActuals1);

            var doubleActuals2 = PropertyPathParser.GetPath <Fake <double>, double>(x => x.Next.Value);

            Assert.AreSame(doubleActuals1, doubleActuals2);
            Assert.AreNotSame(intActuals1, doubleActuals2);

            var doubleFake     = new Fake <double>();
            var doubleActuals3 = PropertyPathParser.GetPath(() => doubleFake.Next.Value);

            Assert.AreSame(doubleActuals1, doubleActuals3);
            Assert.AreNotSame(intActuals1, doubleActuals2);
        }
Example #4
0
        public void Single_Property_With_Null_Final_Value_Should_Return_Correct_Chain()
        {
            var source = new
            {
                Foo = 1,
                Bar = (object)null,
            };

            var expected = new[]
            {
                new PropertyPathToken
                {
                    Type         = PropertyPathTokenType.Valid,
                    Object       = source,
                    PropertyName = "Bar",
                },
                new PropertyPathToken
                {
                    Type         = PropertyPathTokenType.FinalValue,
                    Object       = null,
                    PropertyName = null,
                },
            };

            PropertyPathParser target = new PropertyPathParser();

            PropertyPathToken[] result = target.Parse(source, "Bar").ToArray();

            CollectionAssert.AreEqual(expected, result);
        }
Example #5
0
        public void ResolveType_NestedType_ReturnsExpectedType()
        {
            var path = new PropertyPathParser().Parse("ClassB.ClassC.Name");
            var type = path.ResolveType(typeof(ClassA));

            Assert.AreEqual(typeof(string), type);
        }
Example #6
0
        private static object ConvertPropertyPath(XamlTypeConverter converter, ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string           typename;
            string           propertyname;
            string           index;
            PropertyNodeType node;
            string           str = (string)value;

            // Fastpath - if there are no prefixed types then we have nothing to expand
            if (!str.Contains(":"))
            {
                return(new PropertyPath(str));
            }

            var parser   = new PropertyPathParser(str);
            var expanded = new StringBuilder();

            while ((node = parser.Step(out typename, out propertyname, out index)) != PropertyNodeType.None)
            {
                switch (node)
                {
                case PropertyNodeType.AttachedProperty:
                    if (expanded.Length > 0)
                    {
                        expanded.Append('.');
                    }

                    if (typename.Contains(":"))
                    {
                        typename = converter.parser.ResolveType(typename).ToString();
                        expanded.AppendFormat("('{0}'.{1})", typename, propertyname);
                    }
                    else
                    {
                        expanded.AppendFormat("({0}.{1})", typename, propertyname);
                    }
                    break;

                case PropertyNodeType.Indexed:
                    expanded.AppendFormat("[{0}]", index);
                    break;

                case PropertyNodeType.Property:
                    if (expanded.Length > 0)
                    {
                        expanded.Append('.');
                    }

                    expanded.Append(propertyname);
                    break;

                default:
                    throw new Exception(string.Format("Could not handle PropertyNodeType.{0}", node));
                }
            }

            return(new PropertyPath(str, expanded.ToString()));
        }
        public void GetPathOneItemFuncOfTOneItemNoThis()
        {
#pragma warning disable SA1101 // Prefix local calls with this
            var properties1 = PropertyPathParser.GetPath(() => IsTrue);
#pragma warning restore SA1101 // Prefix local calls with this
            CollectionAssert.AreEqual(new[] { this.GetType().GetProperty(nameof(this.IsTrue), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) }, properties1);
            var properties2 = PropertyPathParser.GetPath(() => this.IsTrue);
            Assert.AreSame(properties1, properties2);
        }
        public void GetPathOneItemFuncOfTOneItemWithThis()
        {
            var properties1 = PropertyPathParser.GetPath(() => this.IsTrue);

            CollectionAssert.AreEqual(new[] { this.GetType().GetProperty("IsTrue") }, properties1);
            var properties2 = PropertyPathParser.GetPath(() => this.IsTrue);

            Assert.AreSame(properties1, properties2);
        }
        public void GetPathOneItemFuncOfTOneItemNoThis()
        {
#pragma warning disable SA1101 // Prefix local calls with this
            var properties1 = PropertyPathParser.GetPath(() => IsTrue);
#pragma warning restore SA1101 // Prefix local calls with this
            CollectionAssert.AreEqual(new[] { this.GetType().GetProperty("IsTrue") }, properties1);
            var properties2 = PropertyPathParser.GetPath(() => this.IsTrue);
            Assert.AreSame(properties1, properties2);
        }
        public void GetPathOneItem3()
        {
            var properties1 = PropertyPathParser.GetPath(() => this.IsTrue);

            CollectionAssert.AreEqual(new[] { this.GetType().GetProperty("IsTrue") }, properties1);
            var properties2 = PropertyPathParser.GetPath <PropertyPathParserTests, bool>(x => x.IsTrue);

            Assert.AreSame(properties1, properties2);
        }
Example #11
0
        public void Parse_InValidPath_ThrowsFormatException(string path)
        {
            var parser = new PropertyPathParser();

            Assert.Throws <FormatException>(() =>
            {
                parser.Parse(path);
            });
        }
        public void When_PropertyPath_Is_A_Reference_Object_Without_Chain()
        {
            XPMemberInfo associationMemberInfo = GetAssociationMemberInfo();
            Isolate.WhenCalled(() => ReflectorHelper.GetXpMemberInfo(null,"Category")).WithExactArguments().WillReturn(associationMemberInfo);
            var propertyPathParser = new PropertyPathParser(null);
            CriteriaOperator criteriaOperator = propertyPathParser.Parse("Category","SomeProperty=50");

            Assert.AreEqual(new BinaryOperator("Category.SomeProperty",50).ToString(), criteriaOperator.ToString());
        }
        public void ReadOnlyCollectionAndReadOnlyObservableCollectionCount()
        {
            var actuals1 = PropertyPathParser.GetPath <ReadOnlyObservableCollection <int>, int>(x => x.Count);

            CollectionAssert.AreEqual(new[] { typeof(ReadOnlyObservableCollection <int>).GetProperty("Count") }, actuals1);
            var actuals2 = PropertyPathParser.GetPath <ReadOnlyCollection <int>, int>(f => f.Count);

            CollectionAssert.AreEqual(new[] { typeof(ReadOnlyCollection <int>).GetProperty("Count") }, actuals2);
        }
        public void GetPathOneItem3()
        {
            var properties1 = PropertyPathParser.GetPath(() => this.IsTrue);

            CollectionAssert.AreEqual(new[] { this.GetType().GetProperty(nameof(this.IsTrue), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) }, properties1);
            var properties2 = PropertyPathParser.GetPath <PropertyPathParserTests, bool>(x => x.IsTrue);

            Assert.AreSame(properties1, properties2);
        }
        public void ReadOnlyCollectionAndReadOnlyObservableCollectionCount()
        {
            var actuals1 = PropertyPathParser.GetPath <ReadOnlyObservableCollection <int>, int>(x => x.Count);

            CollectionAssert.AreEqual(new[] { typeof(ReadOnlyObservableCollection <int>).GetProperty(nameof(ReadOnlyCollection <int> .Count), BindingFlags.Public | BindingFlags.Instance) }, actuals1);
            var actuals2 = PropertyPathParser.GetPath <ReadOnlyCollection <int>, int>(f => f.Count);

            CollectionAssert.AreEqual(new[] { typeof(ReadOnlyCollection <int>).GetProperty(nameof(ReadOnlyCollection <int> .Count), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) }, actuals2);
        }
        public void AttachedPropertyTest()
        {
            string text = "(ownerType.propertyName)";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.AttachedProperty, "ownerType.propertyName")
                           );
        }
        public void SimplePropertyTest()
        {
            string text = "Test";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.PropertyOrType, "Test")
                           );
        }
        public void SimpleIndexerTest()
        {
            string text = "[key]";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.Indexer, "key")
                           );
        }
        public void MultipleIndexerTest()
        {
            string text = "[index1,index2]";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.Indexer, "index1,index2")
                           );
        }
        public void SourceTraversalTest()
        {
            string text = "propertyName/propertyNameX";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.SourceTraversal, "propertyName/propertyNameX")
                           );
        }
        public void ControlChar2()
        {
            string text = "(";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.ControlChar, "(")
                           );
        }
Example #22
0
        public void When_PropertyPath_Is_A_Reference_Object_Without_Chain()
        {
            XPMemberInfo associationMemberInfo = GetAssociationMemberInfo();

            Isolate.WhenCalled(() => XpandReflectionHelper.GetXpMemberInfo(null, "Category")).WithExactArguments().WillReturn(associationMemberInfo);
            var propertyPathParser            = new PropertyPathParser(null, Session.DefaultSession);
            CriteriaOperator criteriaOperator = propertyPathParser.Parse("Category", "SomeProperty=50");

            Assert.AreEqual(new BinaryOperator("Category.SomeProperty", 50).ToString(), criteriaOperator.ToString());
        }
        public void When_PropertyPath_Is_A_Collection_Without_Chain()
        {
            XPMemberInfo collectionMemberInfo = GetCollectionMemberInfo();
            Isolate.WhenCalled(() => ReflectorHelper.GetXpMemberInfo(null,"Orders")).WithExactArguments().WillReturn(collectionMemberInfo);
            var parser = new PropertyPathParser(null);

            CriteriaOperator criteriaOperator= parser.Parse("Orders", "Amount=50");

            Assert.AreEqual("[Orders][[Amount] = 50]", criteriaOperator.ToString());
        }
        public void TwoPartsTest()
        {
            string text = "propertyName.propertyName2";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.PropertyOrType, "propertyName"),
                           new PropertyPathSegment(SegmentKind.PropertyOrType, "propertyName2")
                           );
        }
        public void When_PropertyPath_Is_A_Reference_Object_With_A_Reference_Object_In_Chain()
        {   
            XPMemberInfo associationMemberInfo = GetAssociationMemberInfo();
            Isolate.WhenCalled(() => ReflectorHelper.GetXpMemberInfo(null,"Order")).WillReturn(associationMemberInfo);
            Isolate.WhenCalled(() => ReflectorHelper.GetXpMemberInfo(null, "Order.OrderLine")).WillReturn(associationMemberInfo);
            var parser = new PropertyPathParser(null);

            CriteriaOperator criteriaOperator = parser.Parse("Order.OrderLine", "Amount=50");

            Assert.AreEqual(new BinaryOperator("Order.OrderLine.Amount", 50).ToString(), criteriaOperator.ToString());
        }
Example #26
0
        /// <summary>
        /// Returns the name of a property provided as a property expression.
        /// </summary>
        /// <typeparam name="T">
        /// Type of the property.
        /// </typeparam>
        /// <param name="property">
        /// Property expression on the the form () =&gt; Instance.Property.
        /// </param>
        /// <param name="allowNestedProperty">
        /// Throw an exception if the provided path is a multi level path (e.g. a.b)
        /// </param>
        /// <returns>
        /// Returns the simple name of the property.
        /// </returns>
        //// ReSharper disable once UnusedParameter.Global
        public static string Property <T>(Expression <Func <T> > property, bool allowNestedProperty = false)
        {
            var path = PropertyPathParser.GetPath(property);

            if (path.Count > 1 && !allowNestedProperty)
            {
                throw new ArgumentException("Trying to get the name of a nested property: " + string.Join(".", path.Select(x => x.Name)));
            }

            return(path[path.Count - 1].Name);
        }
        public void MixedTest1()
        {
            string text = "(testType.prop).(someType.as";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.AttachedProperty, "testType.prop"),
                           new PropertyPathSegment(SegmentKind.AttachedProperty, "(someType.as")
                           );
        }
        public void ControlChar4()
        {
            string text = "(testType.";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.AttachedProperty, "(testType"),
                           new PropertyPathSegment(SegmentKind.ControlChar, ".")
                           );
        }
Example #29
0
        public void When_Parameter_Is_A_Chain()
        {
            XPMemberInfo collectionMemberInfo = GetCollectionMemberInfo();

            Isolate.WhenCalled(() => XpandReflectionHelper.GetXpMemberInfo(null, "Customers")).WithExactArguments().WillReturn(collectionMemberInfo);
            var parser = new PropertyPathParser(null, Session.DefaultSession);

            CriteriaOperator criteriaOperator = parser.Parse("Customers", "Order.OrderLine.Ammount=50");

            Assert.AreEqual(new ContainsOperator("Customers", new BinaryOperator("Order.OrderLine.Ammount", 50)).ToString(), criteriaOperator.ToString());
        }
Example #30
0
        public void When_PropertyPath_Is_A_Collection_Without_Chain()
        {
            XPMemberInfo collectionMemberInfo = GetCollectionMemberInfo();

            Isolate.WhenCalled(() => XpandReflectionHelper.GetXpMemberInfo(null, "Orders")).WithExactArguments().WillReturn(collectionMemberInfo);
            var parser = new PropertyPathParser(null, Session.DefaultSession);

            CriteriaOperator criteriaOperator = parser.Parse("Orders", "Amount=50");

            Assert.AreEqual("[Orders][[Amount] = 50]", criteriaOperator.ToString());
        }
        public void ControlChar3()
        {
            string text = "test[";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.PropertyOrType, "test"),
                           new PropertyPathSegment(SegmentKind.ControlChar, "[")
                           );
        }
Example #32
0
        /// <summary>
        /// Returns the name of a property provided as a property expression.
        /// </summary>
        /// <typeparam name="TItem">
        /// Type of the item.
        /// </typeparam>
        /// <typeparam name="TValue">
        /// Type of the property.
        /// </typeparam>
        /// <param name="property">
        /// Property expression on the the form () =&gt; Instance.Property.
        /// </param>
        /// <returns>
        /// Returns the simple name of the property.
        /// </returns>
        public static string Property <TItem, TValue>(Expression <Func <TItem, TValue> > property)
        {
            if (property is null)
            {
                throw new ArgumentNullException(nameof(property));
            }

            var path = PropertyPathParser.GetPath(property);

            return(path[path.Count - 1].Name);
        }
        public void ComplexTest2()
        {
            string text = "(TextBlock.Background).(SolidColorBrush.Color)";

            PropertyPathSegment[] result = PropertyPathParser.Parse(text).ToArray();

            CompareResults(result,
                           new PropertyPathSegment(SegmentKind.AttachedProperty, "TextBlock.Background"),
                           new PropertyPathSegment(SegmentKind.AttachedProperty, "SolidColorBrush.Color")
                           );
        }
Example #34
0
		public PropertyPathWalker (string path, bool bindDirectlyToSource, bool bindsToView, bool isDataContextBound)
		{
			IsDataContextBound = isDataContextBound;

			string index;
			string propertyName;
			string typeName;
			PropertyNodeType type;
			CollectionViewNode lastCVNode = null;
			Path = path;

			if (string.IsNullOrEmpty (path) || path == ".") {
				// If the property path is null or empty, we still need to add a CollectionViewNode
				// to handle the case where we bind diretly to a CollectionViewSource. i.e. new Binding () { Source = cvs }
				// An empty path means we always bind directly to the view.
				Node = new CollectionViewNode (bindDirectlyToSource, bindsToView);
				lastCVNode = (CollectionViewNode) Node;
				FinalNode = Node;
			} else {
				var parser = new PropertyPathParser (path);
				while ((type = parser.Step (out typeName, out propertyName, out index)) != PropertyNodeType.None) {
					bool isViewProperty = CollectionViewProperties.Any (prop => prop.Name == propertyName);
					IPropertyPathNode node = new CollectionViewNode (bindDirectlyToSource, isViewProperty);
					lastCVNode = (CollectionViewNode) node;
					switch (type) {
					case PropertyNodeType.AttachedProperty:
					case PropertyNodeType.Property:
						node.Next = new StandardPropertyPathNode (typeName, propertyName);
						break;
					case PropertyNodeType.Indexed:
						node.Next = new IndexedPropertyPathNode (index);
						break;
					default:
						throw new Exception ("Unsupported node type");
					}
					
					if (FinalNode != null)
						FinalNode.Next = node;
					else
						Node = node;
					
					FinalNode = node.Next;
				}
			}

			lastCVNode.BindToView |= bindsToView;
			FinalNode.IsBrokenChanged += delegate (object o, EventArgs e) {
				Value = ((PropertyPathNode) o).Value;
				var h = IsBrokenChanged;
				if (h != null)
					h (this, EventArgs.Empty);
			};
			FinalNode.ValueChanged += delegate (object o, EventArgs e) {
				Value = ((PropertyPathNode) o).Value;
				var h = ValueChanged;
				if (h != null)
					h (this, EventArgs.Empty);
			};
		}
Example #35
0
 public static PropertyPath Parse(string value, XamlNamespaces namespaces = null)
 {
     PropertyPathParser parser = new PropertyPathParser(value, namespaces ?? XamlNamespaces.Empty);
     return new PropertyPath(parser.Parse());
 }
Example #36
0
		private static object ConvertPropertyPath (XamlTypeConverter converter, ITypeDescriptorContext context, CultureInfo culture, object value)
		{
			string typename;
			string propertyname;
			string index;
			PropertyNodeType node;
			string str = (string) value;

			// Fastpath - if there are no prefixed types then we have nothing to expand
			if (!str.Contains (":"))
				return new PropertyPath (str);

			var parser = new PropertyPathParser (str);
			var expanded = new StringBuilder ();
			while ((node = parser.Step (out typename, out propertyname, out index)) != PropertyNodeType.None) {
				switch (node) {
				case PropertyNodeType.AttachedProperty:
					if (expanded.Length > 0)
						expanded.Append ('.');

					if (typename.Contains (":")) {
						typename = converter.parser.ResolveType (typename).ToString ();
						expanded.AppendFormat ("('{0}'.{1})", typename, propertyname);
					} else {
						expanded.AppendFormat ("({0}.{1})", typename, propertyname);
					}
					break;
				case PropertyNodeType.Indexed:
					expanded.AppendFormat ("[{0}]", index);
					break;
				case PropertyNodeType.Property:
					if (expanded.Length > 0)
						expanded.Append ('.');

					expanded.Append (propertyname);
					break;
				default:
					throw new Exception (string.Format ("Could not handle PropertyNodeType.{0}", node));
				}
			}

			return new PropertyPath (str, expanded.ToString ());
		}
 private CriteriaOperator SetCollectionSourceCriteria(FiltersByCollectionWrapper filtersByCollectionWrapper)
 {
     CriteriaOperator criteriaOperator = CriteriaOperator.Parse(filtersByCollectionWrapper.PropertyPathFilter);
     if (criteriaOperator != null) {
         new FilterWithObjectsProcessor(View.ObjectSpace).Process(criteriaOperator,FilterWithObjectsProcessorMode.StringToObject);
         var criterion = new PropertyPathParser(View.ObjectSpace.Session.GetClassInfo(View.ObjectTypeInfo.Type)).Parse(filtersByCollectionWrapper.PropertyPath, criteriaOperator.ToString());
         ((ListView) View).CollectionSource.Criteria[filtersByCollectionWrapper.ID] =criterion;
         return criteriaOperator;
     }
     return criteriaOperator;
 }
        public void When_PropertyPath_Is_A_Reference_Object_With_A_Collection_And_A_Collection_In_Chain()
        {
            XPMemberInfo collectionMemberInfo = GetCollectionMemberInfo();
            XPMemberInfo associationMemberInfo = GetAssociationMemberInfo();
            Isolate.WhenCalled(() => ReflectorHelper.GetXpMemberInfo(null, "Customer")).WithExactArguments().WillReturn(associationMemberInfo);
            Isolate.WhenCalled(() => ReflectorHelper.GetXpMemberInfo(null, "Customer.Orders")).WithExactArguments().WillReturn(collectionMemberInfo);
            Isolate.WhenCalled(() => ReflectorHelper.GetXpMemberInfo(null, "Customer.Orders.OrderLines")).WithExactArguments().WillReturn(collectionMemberInfo);
            var parser = new PropertyPathParser(null);

            CriteriaOperator criteriaOperator= parser.Parse("Customer.Orders.OrderLines", "Ammount=50");

            Assert.AreEqual(new ContainsOperator("Customer.Orders",new ContainsOperator("OrderLines",new BinaryOperator("Ammount",50))).ToString(), criteriaOperator.ToString());
        }