/*
* JBoss, Home of Professional Open Source.
* Copyright 2015, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.cli.parsing.ifelse.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.jboss.as.cli.CommandFormatException;
import org.jboss.as.cli.completion.mock.MockCommandContext;
import org.jboss.as.cli.handlers.ifelse.ConditionArgument;
import org.jboss.as.cli.handlers.ifelse.IfHandler;
import org.jboss.as.cli.handlers.ifelse.ModelNodePathOperand;
import org.jboss.as.cli.handlers.ifelse.Operand;
import org.jboss.as.cli.handlers.ifelse.Operation;
import org.jboss.as.cli.handlers.ifelse.StringValueOperand;
import org.jboss.as.cli.operation.impl.DefaultCallbackHandler;
import org.jboss.as.cli.operation.impl.DefaultOperationRequestAddress;
import org.junit.BeforeClass;
import org.junit.Test;
/**
*
* @author Alexey Loubyansky
*/
public class IfExpressionParsingTestCase {
static final String AND = "&&";
static final String OR = "||";
static final String EQ = "==";
static final String NOT_EQ = "!=";
static final String GT = ">";
static final String LT = "<";
static final String NGT = "<=";
static final String NLT = ">=";
private static MockCommandContext CTX;
private static DefaultOperationRequestAddress ADDRESS;
private static DefaultCallbackHandler LINE;
private static ConditionArgument CONDITION;
@BeforeClass
public static void setup() throws Exception {
CTX = new MockCommandContext();
ADDRESS = new DefaultOperationRequestAddress();
LINE = new DefaultCallbackHandler();
final IfHandler ifHandler = new IfHandler();
CONDITION = ifHandler.getConditionArgument();
}
@Test
public void testParenthesesMixed() throws Exception {
Operation op = parseExpression("(((a==b || c<=d && e>f) && g!=h || i>=j) && (k<l && m>n || o==p))");
assertOperation(op, AND, 2);
final List<Operand> topOperands = op.getOperands();
Operand operand = topOperands.get(0);
assertOperation(operand, OR, 2);
Operation or = (Operation) operand;
operand = or.getOperands().get(0);
assertOperation(operand, AND, 2);
Operation and = (Operation) operand;
operand = and.getOperands().get(0);
assertOperation(operand, OR, 2);
assertComparison(((Operation)operand).getOperands().get(0), EQ, "a", "b");
Operand cdAndEf = ((Operation)operand).getOperands().get(1);
assertOperation(cdAndEf, AND, 2);
assertComparison(((Operation)cdAndEf).getOperands().get(0), NGT, "c", "d");
assertComparison(((Operation)cdAndEf).getOperands().get(1), GT, "e", "f");
operand = and.getOperands().get(1);
assertComparison(operand, NOT_EQ, "g", "h");
operand = or.getOperands().get(1);
assertComparison(operand, NLT, "i", "j");
operand = topOperands.get(1);
assertOperation(operand, OR, 2);
or = (Operation) operand;
operand = or.getOperands().get(0);
assertOperation(operand, AND, 2);
assertComparison(((Operation)operand).getOperands().get(0), LT, "k", "l");
assertComparison(((Operation)operand).getOperands().get(1), GT, "m", "n");
assertComparison(or.getOperands().get(1), EQ, "o", "p");
}
@Test
public void testSimpleParentheses() throws Exception {
Operation op = parseExpression("( a >=b && (c<d || e> f )&& g != h )");
assertOperation(op, AND, 3);
final List<Operand> operands = op.getOperands();
Operand operand = operands.get(0);
assertComparison(operand, NLT, "a", "b");
operand = operands.get(1);
assertOperation(operand, OR, 2);
assertComparison(((Operation)operand).getOperands().get(0), LT, "c", "d");
assertComparison(((Operation)operand).getOperands().get(1), GT, "e", "f");
operand = operands.get(2);
assertComparison(operand, NOT_EQ, "g", "h");
}
@Test
public void testMixNoParentheses() throws Exception {
Operation op = parseExpression("( a>b && c>=d && e<f || g <= h && i==j || k != l)");
assertOperation(op, OR, 3);
final List<Operand> operands = op.getOperands();
Operand operand = operands.get(0);
assertOperation(operand, AND, 3);
assertComparison(((Operation)operand).getOperands().get(0), GT, "a", "b");
assertComparison(((Operation)operand).getOperands().get(1), NLT, "c", "d");
assertComparison(((Operation)operand).getOperands().get(2), LT, "e", "f");
operand = operands.get(1);
assertOperation(operand, AND, 2);
assertComparison(((Operation)operand).getOperands().get(0), NGT, "g", "h");
assertComparison(((Operation)operand).getOperands().get(1), EQ, "i", "j");
operand = operands.get(2);
assertComparison(operand, NOT_EQ, "k", "l");
}
@Test
public void testOrSequence() throws Exception {
Operation op = parseExpression("(a == b || c== d||e==f)");
assertOperation(op, OR, 3);
final List<Operand> operands = op.getOperands();
assertComparison(operands.get(0), EQ, "a", "b");
assertComparison(operands.get(1), EQ, "c", "d");
assertComparison(operands.get(2), EQ, "e", "f");
}
@Test
public void testAndSequence() throws Exception {
Operation op = parseExpression("(a==b && c == d && e == f)");
assertOperation(op, AND, 3);
final List<Operand> operands = op.getOperands();
assertComparison(operands.get(0), EQ, "a", "b");
assertComparison(operands.get(1), EQ, "c", "d");
assertComparison(operands.get(2), EQ, "e", "f");
}
@Test
public void testOrAndSequence() throws Exception {
Operand op = parseExpression("(a == b || c == d && e == f)");
assertOperation(op, "||", 2);
List<Operand> operands = ((Operation) op).getOperands();
assertComparison(operands.get(0), EQ, "a", "b");
op = operands.get(1);
assertOperation(op, "&&", 2);
operands = ((Operation) op).getOperands();
assertComparison(operands.get(0), EQ, "c", "d");
assertComparison(operands.get(1), EQ, "e", "f");
}
@Test
public void testAndOrSequence() throws Exception {
Operand op = parseExpression("(a == b && c == d || e == f)");
assertOperation(op, "||", 2);
List<Operand> operands = ((Operation) op).getOperands();
assertComparison(operands.get(1), EQ, "e", "f");
op = operands.get(0);
assertOperation(op, "&&", 2);
operands = ((Operation) op).getOperands();
assertComparison(operands.get(0), EQ, "a", "b");
assertComparison(operands.get(1), EQ, "c", "d");
}
@Test
public void testNoParenthesis() throws Exception {
Operand op = parseExpression("result.value==true");
assertOperation(op, "==", 2);
List<Operand> operands = ((Operation) op).getOperands();
assertEquals("result.value", operands.get(0).toString());
assertEquals("true", operands.get(1).toString());
assertTrue(operands.get(0) instanceof ModelNodePathOperand);
}
@Test
public void testQuotedSpecialCharacters() throws Exception {
Operation op = parseExpression("(outcome == success && result.value != \"a64180c0)e7187af86b435229de904104\\\"\")");
assertOperation(op, AND, 2);
assertComparison(((Operation)op).getOperands().get(0), EQ, "outcome", "success");
assertComparison(((Operation)op).getOperands().get(1), NOT_EQ, "result.value", "\"a64180c0)e7187af86b435229de904104\"\"");
op = parseExpression("(outcome == success && result.value != a64180c0\\)e7187af86b435229de904104\\\")");
assertOperation(op, AND, 2);
assertComparison(((Operation)op).getOperands().get(0), EQ, "outcome", "success");
assertComparison(((Operation)op).getOperands().get(1), NOT_EQ, "result.value", "a64180c0)e7187af86b435229de904104\"");
}
protected void assertOperation(Operand operand, String opName, int operandsTotal) {
assertTrue(operand instanceof Operation);
assertEquals(opName, ((Operation)operand).getName());
assertEquals(operandsTotal, ((Operation)operand).getOperands().size());
}
protected void assertComparison(Operand operand, String opName, String left, String right) {
assertNotNull(operand);
assertTrue(operand instanceof Operation);
Operation op = (Operation) operand;
assertEquals(opName, op.getName());
assertNotNull(op.getOperands());
assertEquals(2, op.getOperands().size());
assertEquals(left, op.getOperands().get(0).toString());
assertEquals(right, op.getOperands().get(1).toString());
// for the given impl the below is expected to be true
assertTrue(op.getOperands().get(0) instanceof ModelNodePathOperand);
assertTrue(op.getOperands().get(1) instanceof StringValueOperand);
}
protected Operation parseExpression(String condition) throws CommandFormatException {
LINE.parse(ADDRESS, "if " + condition + " of /a=b:c", CTX);
return CONDITION.resolveOperation(LINE);
}
}