Subversion Repositories mkgmap

Rev

Rev 4464 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2017.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 or
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */


package uk.me.parabola.mkgmap.osmstyle;

import java.io.StringReader;
import java.util.Iterator;

import uk.me.parabola.mkgmap.osmstyle.eval.ExpressionReader;
import uk.me.parabola.mkgmap.osmstyle.eval.LinkedOp;
import uk.me.parabola.mkgmap.osmstyle.eval.NodeType;
import uk.me.parabola.mkgmap.osmstyle.eval.Op;
import uk.me.parabola.mkgmap.reader.osm.FeatureKind;
import uk.me.parabola.mkgmap.scan.TokenScanner;

import org.junit.Test;

import static org.junit.Assert.*;
import static uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.fmtExpr;
import static uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.isSolved;
import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.AND;
import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.EQUALS;


public class ExpressionArrangerTest {
        private final ExpressionArranger arranger = new ExpressionArranger();

        @Test
        public void testChainedAnd() {

                Op op = createOp("(a>2 & b~h) & c=* & d=hello & fred<3 [0x2]");
                op = arranger.arrange(op);

                assertEquals("$d=hello [AND] $c=* & $a>2 & $fred<3 & $b~h", fmtExpr(op));
        }

        @Test
        public void testChainAndWithBracketedAnd() {
                Op op = createOp("(a>2 & b~h) & (c=* & d=hello) & fred<3 [0x2]");
                op = arranger.arrange(op);

                assertTrue(fmtExpr(op).startsWith("$d=hello [AND] $c=* & "));
        }

        @Test
        public void testPoorInitialSwap() {
                Op op = createOp("!($b=1) & $b!=1 & $b!=2 & $b=1 {name 'n770'} [0x2]");
                op = arranger.arrange(op);

                System.out.println(fmtExpr(op));
                assertTrue(fmtExpr(op).startsWith("$b=1 [AND] "));
        }

        @Test
        public void testStartDoubleNot() {
                Op op = createOp("!!(a<2 & b=foo)");
                op = arranger.arrange(op);

                assertEquals("$b=foo & $a<2", op.toString());
        }

        @Test
        public void testBasicOr() {
                Op op = createOp("a<2 & b=1 | a<1 & b=2");
                op = arranger.arrange(op);

                assertTrue(isSolved(op));
        }

        @Test
        public void testChainedOr() {
                Op op = createOp("a<2 & b=1 | a<1 & b=2 | a<2 & b!=2 & c=hello");
                op = arranger.arrange(op);

                assertTrue(isSolved(op));
        }

        @Test
        public void testNotFailed() {
                Op op = createOp("!($a < 1 | $a != 2) & $a != 2");
                op = arranger.arrange(op);

                assertTrue(isSolved(op));
        }

        @Test
        public void testIsSolved() {
                String s = "$a=2 | $a=1 & $a!=1 | $b=2 & $a!=1 | $b<1";
                Op op = createOp(s);
                assertTrue(isSolved(op));

                op = arranger.arrange(op);
                assertTrue(isSolved(op));
        }

        @Test
        public void testDistributeFailure() {
                Op op = createOp("($b<2 | $b<1) & ($a=1 | $b~2 | !($a=1)) & $a!=2");
                System.out.println(fmtExpr(op));
                op = arranger.arrange(op);
                assertTrue(isSolved(op));

                System.out.println(fmtExpr(op));
        }

        @Test
        public void testOrWithNotFailure() {
                Op op = createOp("$b<2 | !($b!=1 & $b!=2) | $a~1 {name 'n466'} [0x2]");
                System.out.println(fmtExpr(op));
                op = arranger.arrange(op);
                System.out.println(fmtExpr(op));
                assertTrue(isSolved(op));
        }

        @Test
        public void testComplex1() {
                Op op = createOp("($a=2 | $b~2 | $a=2 | $a<1) & ($a!=1 | $b<2 | !($a=1) | $b=1) & $b!=1 {name 'n866'} [0x2]");
                op = arranger.arrange(op);
                assertTrue(isSolved(op));
        }

        @Test
        public void testQuadNot() {
                Op op = createOp("!!!!($a<2) & length()>=1 {name 'n989225'} [0x2]");
                op = arranger.arrange(op);
                assertTrue(isSolved(op));
        }

        @Test
        public void testExistsWithNot() {
                Op op = createOp("!($a=*) & $a=1 [0x1]");
                op = arranger.arrange(op);
                assertTrue(isSolved(op));
        }

        @Test
        public void testPrepareOrSimple() {
                Op op = createOp("a=3 | b < 2");  // Just one or
                op = arranger.arrange(op);
                Iterator<Op> it = arranger.prepareForSave(op);

                boolean first = true;
                while (it.hasNext()) {
                        Op o = it.next();
                        assertTrue("Prepared OR should all be LinkedOp's", o instanceof LinkedOp);
                        assertEquals("Only first should have first flag set", first, ((LinkedOp) o).isFirstPart());
                        first = false;
                        assertTrue(isSolved(o));
                        System.out.println(o);
                }
        }

        @Test
        public void testPrepareOr() {
                Op op = createOp("a=3 | b < 2 | c=*");
                op = arranger.arrange(op);
                Iterator<Op> it = arranger.prepareForSave(op);

                boolean first = true;
                while (it.hasNext()) {
                        Op o = it.next();
                        assertTrue("Prepared OR should all be LinkedOp's", o instanceof LinkedOp);
                        assertEquals("Only first should have first flag set", first, ((LinkedOp) o).isFirstPart());
                        first = false;
                        assertTrue(isSolved(o));
                        System.out.println(o);
                }
        }

        @Test
        public void testShouldNotCombineEquals() {
                Op op = createOp("a=3");
                Iterator<Op> it = arranger.prepareForSave(op);
                op = it.next();
                assertEquals(EQUALS, op.getType());
        }

        @Test
        public void testExitsAndFunction() {
                Op op = createOp("$a=* & is_closed()=true {name 'n466'} [0x2]");
                System.out.println(fmtExpr(op));
                op = arranger.arrange(op);
                System.out.println(fmtExpr(op));
                assertTrue(isSolved(op));
                assertTrue(op.getFirst().getType() != NodeType.FUNCTION);
        }

        @Test
        public void testExistsAndFunctionWithOr() {
                Op op = createOp("area_size() < 25000 & (fixme = * | FIXME=*) [0x2]");
                System.out.println(fmtExpr(op));
                op = arranger.arrange(op);
                System.out.println(fmtExpr(op));
                assertTrue(isSolved(op));
                assertTrue(op.getFirst().getType() != NodeType.FUNCTION);
        }

        @Test
        public void testTwoFunctionsDifferentComplexity() {
                Op op = createOp("a=1 & is_in(landuse,residential,all)=true & length()< 10 [0x02]");
                op = arranger.arrange(op);

                String formatted = fmtExpr(op);
                System.out.println(formatted);
                int posLen = formatted.indexOf("length");
                int posIsIn = formatted.indexOf("is_in");
                assertTrue(posLen >= 0);
                assertTrue(posIsIn >= 0);
                assertTrue(posLen < posIsIn);
        }

        @Test
        public void testEqualTagValue() {
                Op op = createOp("c!=d & a=$b");
                op = arranger.arrange(op);
                Iterator<Op> it = arranger.prepareForSave(op);
                op = it.next();
                assertEquals(AND, op.getType());
                assertEquals("$a=* & $a=$b & $c!=d", op.toString());
                System.out.println(op.toString());
        }

        private Op createOp(String s) {
                TokenScanner scanner = new TokenScanner("test.file", new StringReader(s));
                ExpressionReader er = new ExpressionReader(scanner, FeatureKind.POLYLINE);
                return er.readConditions();
        }
}