blob: 0e0636f039b174269cc3af32cc46a88cdfbbf8d1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.metron.stellar.common.shell.cli;
import com.google.common.collect.Iterables;
import org.jboss.aesh.complete.CompleteOperation;
import org.jboss.aesh.console.AeshContext;
import org.jboss.aesh.console.ConsoleOperation;
import org.jboss.aesh.console.operator.ControlOperator;
import org.jboss.aesh.console.settings.DefaultAeshContext;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* Tests the StellarShell class.
*/
public class StellarShellTest {
private StellarShell stellarShell;
private ByteArrayOutputStream out;
private ByteArrayOutputStream err;
@BeforeEach
public void setup() throws Exception {
out = new ByteArrayOutputStream();
err = new ByteArrayOutputStream();
// setup streams so that we can capture stdout
System.setOut(new PrintStream(out, false, StandardCharsets.UTF_8.name()));
System.setErr(new PrintStream(err, false, StandardCharsets.UTF_8.name()));
String[] args = new String[0];
stellarShell = new StellarShell(args);
}
@AfterEach
public void cleanUp() {
System.setOut(null);
System.setErr(null);
}
/**
* @return The data written to stdout during the test (with newlines stripped out to simplify comparisons.)
*/
private String stdout() {
return out.toString().replace(System.lineSeparator(), "");
}
/**
* @return The data written to stdout during the test.
*/
private String stdoutWithNewlines() {
return out.toString();
}
/**
* @return The data written to stderr during the test.
*/
private String stderr() {
return err.toString().replace(System.lineSeparator(), "");
}
/**
* @param buffer
* @return A ConsoleOperation that that StellarShell uses to drive input.
*/
private ConsoleOperation createOp(String buffer) {
return new ConsoleOperation(ControlOperator.APPEND_OUT, buffer);
}
@Test
public void testExecuteStellar() throws Exception {
stellarShell.execute(createOp("2 + 2"));
assertEquals("4", stdout());
}
@Test
public void testBackslashInStrings() throws Exception {
stellarShell.execute(createOp("SPLIT('foo\\\\bar', '\\\\')"));
assertEquals("[foo, bar]", stdout());
}
/**
* Ensure that Stellar lists are displayed correctly in the REPL.
*/
@Test
public void testExecuteWithStellarList() throws Exception {
stellarShell.execute(createOp("[1,2,3,4,5]"));
assertEquals("[1, 2, 3, 4, 5]", stdout());
}
/**
* Ensure that Stellar maps are displayed correctly in the REPL.
*/
@Test
public void testExecuteWithStellarMap() throws Exception {
stellarShell.execute(createOp("{ 'foo':2, 'key':'val' }"));
assertEquals("{foo=2, key=val}", stdout());
}
/**
* Ensure that 'bad' Stellar code is handled correctly by the REPL.
*/
@Test
public void testExecuteBadStellar() throws Exception {
stellarShell.execute(createOp("2 + "));
final String expected = "[!] Unable to parse: 2 + ";
assertTrue(stdout().startsWith(expected));
}
/**
* The REPL should handle if no value is returned. Some Stellar expressions
* will result in no value.
*/
@Test
public void testExecuteNoop() throws Exception {
stellarShell.execute(createOp("x"));
assertEquals("", stdout());
}
/**
* The REPL should handle if the user chooses to quit.
*/
@Test
public void testQuit() throws Exception {
stellarShell.execute(createOp("quit"));
// the console should not be running
assertFalse(stellarShell.getConsole().isRunning());
}
/**
* The REPL should handle if the user chooses to quit.
*/
@Test
public void testStart() throws Exception {
StellarShell.main(new String[0]);
// we should see the welcome prompt
assertTrue(stdoutWithNewlines().contains(StellarShell.WELCOME));
}
/**
* The REPL should support auto-completion.
*/
@Test
public void testAutoComplete() throws Exception {
// the user's input that needs auto-completed
final String buffer = "TO_";
// the cursor is at the end of the buffer
int cursor = buffer.length();
// ask the shell to auto-complete
AeshContext context = new DefaultAeshContext();
CompleteOperation op = new CompleteOperation(context, buffer, cursor);
stellarShell.complete(op);
// we should have some auto-complete candidates
List<String> candidates = op.getFormattedCompletionCandidates();
assertTrue(candidates.size() > 0);
// validate each candidate
for(String candidate: candidates) {
String completion = buffer + candidate;
// the auto-complete should include an open paren
assertEquals("(", completion.substring(completion.length() - 1));
// the candidate should be a valid, defined function
String function = completion.substring(0, completion.length() - 1);
Iterable<String> allFunctions = stellarShell.getExecutor().getFunctionResolver().getFunctions();
String definedFunction = Iterables.find(allFunctions, (fn) -> fn.equals(function));
assertEquals(function, definedFunction);
}
}
}