Beispiel #1
0
        public virtual void TestParsesMultiCorrectly()
        {
            Evaluator eval = QueryParser.Parse(".foo > ol, ol > li + li");

            NUnit.Framework.Assert.IsTrue(eval is CombiningEvaluator.OR);
            CombiningEvaluator.OR or = (CombiningEvaluator.OR)eval;
            NUnit.Framework.Assert.AreEqual(2, or.evaluators.Count);
            CombiningEvaluator.And andLeft  = (CombiningEvaluator.And)or.evaluators[0];
            CombiningEvaluator.And andRight = (CombiningEvaluator.And)or.evaluators[1];
            NUnit.Framework.Assert.AreEqual("ol :ImmediateParent.foo", andLeft.ToString());
            NUnit.Framework.Assert.AreEqual(2, andLeft.evaluators.Count);
            NUnit.Framework.Assert.AreEqual("li :prevli :ImmediateParentol", andRight.ToString());
            NUnit.Framework.Assert.AreEqual(2, andLeft.evaluators.Count);
        }
Beispiel #2
0
        public virtual void TestOrGetsCorrectPrecedence()
        {
            // tests that a selector "a b, c d, e f" evals to (a AND b) OR (c AND d) OR (e AND f)"
            // top level or, three child ands
            Evaluator eval = QueryParser.Parse("a b, c d, e f");

            NUnit.Framework.Assert.IsTrue(eval is CombiningEvaluator.OR);
            CombiningEvaluator.OR or = (CombiningEvaluator.OR)eval;
            NUnit.Framework.Assert.AreEqual(3, or.evaluators.Count);
            foreach (Evaluator innerEval in or.evaluators)
            {
                NUnit.Framework.Assert.IsTrue(innerEval is CombiningEvaluator.And);
                CombiningEvaluator.And and = (CombiningEvaluator.And)innerEval;
                NUnit.Framework.Assert.AreEqual(2, and.evaluators.Count);
                NUnit.Framework.Assert.IsTrue(and.evaluators[0] is Evaluator.Tag);
                NUnit.Framework.Assert.IsTrue(and.evaluators[1] is StructuralEvaluator.Parent);
            }
        }
        private void Combinator(char combinator)
        {
            tq.ConsumeWhitespace();
            String subQuery = ConsumeSubQuery();
            // support multi > childs
            Evaluator rootEval;
            // the new topmost evaluator
            Evaluator currentEval;
            // the evaluator the new eval will be combined to. could be root, or rightmost or.
            Evaluator newEval = Parse(subQuery);
            // the evaluator to add into target evaluator
            bool replaceRightMost = false;

            if (evals.Count == 1)
            {
                rootEval = currentEval = evals[0];
                // make sure OR (,) has precedence:
                if (rootEval is CombiningEvaluator.OR && combinator != ',')
                {
                    currentEval      = ((CombiningEvaluator.OR)currentEval).RightMostEvaluator();
                    replaceRightMost = true;
                }
            }
            else
            {
                rootEval = currentEval = new CombiningEvaluator.And(evals);
            }
            evals.Clear();
            // for most combinators: change the current eval into an AND of the current eval and the new eval
            if (combinator == '>')
            {
                currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.ImmediateParent(currentEval));
            }
            else
            {
                if (combinator == ' ')
                {
                    currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.Parent(currentEval));
                }
                else
                {
                    if (combinator == '+')
                    {
                        currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.ImmediatePreviousSibling(currentEval
                                                                                                                           ));
                    }
                    else
                    {
                        if (combinator == '~')
                        {
                            currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.PreviousSibling(currentEval));
                        }
                        else
                        {
                            if (combinator == ',')
                            {
                                // group or.
                                CombiningEvaluator.OR or;
                                if (currentEval is CombiningEvaluator.OR)
                                {
                                    or = (CombiningEvaluator.OR)currentEval;
                                    or.Add(newEval);
                                }
                                else
                                {
                                    or = new CombiningEvaluator.OR();
                                    or.Add(currentEval);
                                    or.Add(newEval);
                                }
                                currentEval = or;
                            }
                            else
                            {
                                throw new Selector.SelectorParseException("Unknown combinator: " + combinator);
                            }
                        }
                    }
                }
            }
            if (replaceRightMost)
            {
                ((CombiningEvaluator.OR)rootEval).ReplaceRightMostEvaluator(currentEval);
            }
            else
            {
                rootEval = currentEval;
            }
            evals.Add(rootEval);
        }