// This file is part of OpenTSDB. // Copyright (C) 2015 The OpenTSDB Authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 2.1 of the License, or (at your // option) any later version. 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 Lesser // General Public License for more details. You should have received a copy // of the GNU Lesser General Public License along with this program. If not, // see <http://www.gnu.org/licenses/>. package net.opentsdb.query.expression; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.NoSuchElementException; import org.junit.Test; public class TestExpressionReader { final static String EXP = "test(sys.cpu.user)"; @Test public void ctor() throws Exception { final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); assertEquals(EXP, reader.toString()); assertEquals(0, reader.getMark()); assertEquals('t', reader.peek()); } @Test (expected = IllegalArgumentException.class) public void ctorNull() throws Exception { new ExpressionReader(null); } @Test public void ctorEmptyString() throws Exception { final ExpressionReader reader = new ExpressionReader(new char[] { }); assertEquals(0, reader.getMark()); assertTrue(reader.isEOF()); try { reader.peek(); fail("Expected a NoSuchElementException"); } catch (NoSuchElementException e) { } try { reader.next(); fail("Expected a NoSuchElementException"); } catch (NoSuchElementException e) { } try { reader.isNextChar('o'); fail("Expected a NoSuchElementException"); } catch (NoSuchElementException e) { } try { reader.readFuncName(); fail("Expected a NoSuchElementException"); } catch (NoSuchElementException e) { } reader.readNextParameter(); // always false assertFalse(reader.isNextSeq("laska")); // no-op reader.skipWhitespaces(); // doesn't hurt anything reader.skip(52); } @Test public void peek() throws Exception { final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); assertEquals(0, reader.getMark()); assertEquals('t', reader.peek()); reader.next(); assertEquals(1, reader.getMark()); assertEquals('e', reader.peek()); assertEquals(1, reader.getMark()); } @Test public void nextTillEOF() throws Exception { final char[] chars = EXP.toCharArray(); final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); for (final char c : chars) { assertEquals(c, reader.next()); } assertTrue(reader.isEOF()); } @Test public void skip() throws Exception { final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); reader.skip(4); assertEquals(4, reader.getMark()); assertEquals('(', reader.peek()); } @Test public void skipOutOfBounds() throws Exception { final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); reader.skip(EXP.length()); assertEquals(EXP.length(), reader.getMark()); assertTrue(reader.isEOF()); } @Test (expected = UnsupportedOperationException.class) public void skipBackwards() throws Exception { final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); reader.skip(-1); } @Test public void isNextChar() throws Exception { final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); assertTrue(reader.isNextChar('t')); reader.skip(4); assertTrue(reader.isNextChar('(')); assertFalse(reader.isNextChar('t')); } @Test public void isNextSeq() throws Exception { final ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); assertTrue(reader.isNextSeq("test(")); assertFalse(reader.isNextSeq("est(")); assertTrue(reader.isNextSeq(EXP)); assertFalse(reader.isNextSeq(EXP + "morestuff")); } @Test public void readFuncName() { ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); assertEquals("test", reader.readFuncName()); assertEquals("", reader.readFuncName()); assertEquals("", reader.readFuncName()); assertFalse(reader.isEOF()); // space between method and parens reader = new ExpressionReader("test (foo)".toCharArray()); assertEquals("test", reader.readFuncName()); assertEquals("", reader.readFuncName()); // consume initial whitespace reader = new ExpressionReader(" test(foo)".toCharArray()); assertEquals("test", reader.readFuncName()); assertEquals("", reader.readFuncName()); // whitespace everywhere!! reader = new ExpressionReader(" test(foo) ".toCharArray()); assertEquals("test", reader.readFuncName()); assertEquals("", reader.readFuncName()); // nesting fails unless we consume the parens reader = new ExpressionReader("test(foo(bar()))".toCharArray()); assertEquals("test", reader.readFuncName()); assertEquals("", reader.readFuncName()); assertEquals("", reader.readFuncName()); reader = new ExpressionReader("test(foo(bar()))".toCharArray()); assertEquals("test", reader.readFuncName()); reader.next(); assertEquals("foo", reader.readFuncName()); reader.next(); assertEquals("bar", reader.readFuncName()); // parens with space reader = new ExpressionReader("test ( foo ( bar()))".toCharArray()); assertEquals("test", reader.readFuncName()); reader.next(); assertEquals("foo", reader.readFuncName()); reader.next(); assertEquals("bar", reader.readFuncName()); // TODO - Watch out for the following gotchas reader = new ExpressionReader("test ( foo bar()))".toCharArray()); assertEquals("test", reader.readFuncName()); reader.next(); assertEquals("foo", reader.readFuncName()); reader.next(); assertEquals("ar", reader.readFuncName()); reader = new ExpressionReader("test ".toCharArray()); assertEquals("test", reader.readFuncName()); } // TODO - more UTs around this guy @Test public void readNextParameter() { // will read the whole thing, so watch out! ExpressionReader reader = new ExpressionReader(EXP.toCharArray()); assertEquals(EXP, reader.readNextParameter()); // TODO - ok? reader = new ExpressionReader(EXP.toCharArray()); reader.readFuncName(); assertEquals("(sys.cpu.user)", reader.readNextParameter()); // TODO - ok? reader = new ExpressionReader("test(foo,1,2)".toCharArray()); reader.readFuncName(); reader.next(); assertEquals("foo,1,2", reader.readNextParameter()); } }