/*
Copywrite 2015-2016 Will Winder
This file is part of Universal Gcode Sender (UGS).
UGS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
UGS 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.
You should have received a copy of the GNU General Public License
along with UGS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.willwinder.universalgcodesender;
import static com.willwinder.universalgcodesender.AbstractControllerTest.tempDir;
import com.willwinder.universalgcodesender.connection.Connection;
import com.willwinder.universalgcodesender.listeners.SerialCommunicatorListener;
import com.willwinder.universalgcodesender.types.GcodeCommand;
import com.willwinder.universalgcodesender.utils.GcodeStreamReader;
import com.willwinder.universalgcodesender.utils.GcodeStreamTest;
import com.willwinder.universalgcodesender.utils.GcodeStreamWriter;
import java.io.File;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.lang.reflect.Field;
import java.util.concurrent.LinkedBlockingDeque;
import org.apache.commons.io.FileUtils;
import org.easymock.EasyMock;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.Ignore;
/**
*
* @author wwinder
*/
public class BufferedCommunicatorTest {
BufferedCommunicator instance;
LinkedBlockingDeque<String> cb;
LinkedBlockingDeque<GcodeCommand> asl;
final static Connection mockConnection = EasyMock.createMock(Connection.class);
final static SerialCommunicatorListener mockScl = EasyMock.createMock(SerialCommunicatorListener.class);
public BufferedCommunicatorTest() {
}
@BeforeClass
static public void setup() throws IOException {
tempDir = GcodeStreamTest.createTempDirectory();
}
@AfterClass
static public void teardown() throws IOException {
FileUtils.forceDeleteOnExit(tempDir);
}
@Before
public void setUp() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException {
EasyMock.reset(mockConnection, mockScl);
instance = new BufferedCommunicatorImpl();
instance.setConnection(mockConnection);
instance.setListenAll(mockScl);
cb = new LinkedBlockingDeque<>();
asl = new LinkedBlockingDeque<>();
instance.setQueuesForTesting(cb, asl);
// Initialize private variable.
Field f = AbstractCommunicator.class.getDeclaredField("launchEventsInDispatchThread");
f.setAccessible(true);
f.set(instance, false);
EasyMock.reset(mockConnection, mockScl);
}
/**
* Test of getBufferSize method, of class BufferedCommunicator.
*/
@Test
@Ignore
public void testSingleStepMode() {
System.out.println("testSingleStepMode");
fail("Not implemented yet.");
}
/**
* Test of getBufferSize method, of class BufferedCommunicator.
*/
@Test
public void testGetBufferSize() {
System.out.println("getBufferSize");
assertEquals(101, instance.getBufferSize());
}
/**
* Test of queueStringForComm method, of class BufferedCommunicator.
*/
@Test
public void testQueueStringForComm() {
System.out.println("queueStringForComm");
String input = "input";
instance.queueStringForComm(input);
assertEquals(input, cb.getFirst());
}
/**
* Test of streamCommands method, of class BufferedCommunicator.
*/
@Test
public void testSimpleQueueStringsStream() throws Exception {
System.out.println("streamCommands");
String input = "input";
// Check events and connection:
// console message, connection stream, sent event
mockScl.messageForConsole(EasyMock.anyString());
EasyMock.expect(EasyMock.expectLastCall()).times(2);
mockConnection.sendStringToComm(input + "\n");
EasyMock.expect(EasyMock.expectLastCall()).times(2);
mockScl.commandSent(EasyMock.<GcodeCommand>anyObject());
EasyMock.expect(EasyMock.expectLastCall()).times(2);
EasyMock.replay(mockConnection, mockScl);
// Test
instance.queueStringForComm(input);
instance.queueStringForComm(input);
instance.streamCommands();
EasyMock.verify(mockConnection, mockScl);
}
@Test
public void testSimpleRawStreamStream() throws Exception {
String[] inputs = {"input1", "input2"};
for (String i : inputs) {
mockScl.messageForConsole(EasyMock.anyString());
EasyMock.expect(EasyMock.expectLastCall());
mockConnection.sendStringToComm(i + "\n");
EasyMock.expect(EasyMock.expectLastCall());
mockScl.commandSent(EasyMock.<GcodeCommand>anyObject());
EasyMock.expect(EasyMock.expectLastCall());
}
EasyMock.replay(mockConnection, mockScl);
PipedReader in = new PipedReader();
try (PipedWriter out = new PipedWriter(in)) {
for(String i : inputs) {
out.append(i + "\n");
}
}
instance.queueRawStreamForComm(in);
instance.streamCommands();
EasyMock.verify(mockConnection, mockScl);
}
@Test
public void testSimpleStreamStream() throws Exception {
String[] inputs = {"input1", "input2"};
for (String i : inputs) {
mockScl.messageForConsole(EasyMock.anyString());
EasyMock.expect(EasyMock.expectLastCall());
mockConnection.sendStringToComm(i + "\n");
EasyMock.expect(EasyMock.expectLastCall());
mockScl.commandSent(EasyMock.<GcodeCommand>anyObject());
EasyMock.expect(EasyMock.expectLastCall());
}
EasyMock.replay(mockConnection, mockScl);
File f = new File(tempDir,"gcodeFile");
try (GcodeStreamWriter gsw = new GcodeStreamWriter(f)) {
for(String i : inputs) {
gsw.addLine("blah", i, null, -1);
}
}
GcodeStreamReader gsr = new GcodeStreamReader(f);
instance.queueStreamForComm(gsr);
instance.streamCommands();
assertEquals("input1, input2, 0 streaming commands.", instance.activeCommandSummary());
EasyMock.verify(mockConnection, mockScl);
}
/**
* Test of areActiveCommands method, of class BufferedCommunicator.
*/
@Test
public void testActiveCommands() throws Exception {
System.out.println("areActiveCommands");
String input = "input";
// Setup 2 active commands.
mockScl.messageForConsole(EasyMock.anyString());
EasyMock.expect(EasyMock.expectLastCall()).times(2);
mockConnection.sendStringToComm(input + "\n");
EasyMock.expect(EasyMock.expectLastCall()).times(2);
mockScl.commandSent(EasyMock.<GcodeCommand>anyObject());
EasyMock.expect(EasyMock.expectLastCall()).times(2);
// Left an active command.
// Active commands complete.
mockScl.rawResponseListener("ok");
EasyMock.expect(EasyMock.expectLastCall()).times(2);
EasyMock.replay(mockConnection, mockScl);
//////////////
// THE TEST //
//////////////
// No active commands.
assertEquals(false, instance.areActiveCommands());
assertEquals(0, instance.numActiveCommands());
// Leave active commands in pipeline.
instance.queueStringForComm(input);
instance.queueStringForComm(input);
instance.streamCommands();
assertEquals(true, instance.areActiveCommands());
assertEquals(2, instance.numActiveCommands());
assertEquals(input + ", " + input, instance.activeCommandSummary());
// Clear out active commands.
instance.responseMessage("ok");
assertEquals(true, instance.areActiveCommands());
instance.responseMessage("ok");
assertEquals(false, instance.areActiveCommands());
assertEquals(0, instance.numActiveCommands());
EasyMock.verify(mockConnection, mockScl);
}
/**
* Test of pauseSend method, of class BufferedCommunicator.
*/
@Test
public void testPauseSendResume() throws Exception {
System.out.println("pauseSend");
String input = "123456789";
for (int i = 0; i < 11; i++) {
mockConnection.sendStringToComm(input + "\n");
EasyMock.expect(EasyMock.expectLastCall());
}
EasyMock.replay(mockConnection);
// Send the first 10 commands, pause 11th
for (int i = 0; i < 11; i++) {
instance.queueStringForComm(input);
}
instance.streamCommands();
instance.pauseSend();
assertEquals("First 10 commands sent.", 10, asl.size());
for (int i = 0; i < 10; i++) {
instance.responseMessage("ok");
}
assertEquals("First 10 commands done.", 0, asl.size());
// Resume and send the last command.
instance.resumeSend();
assertEquals("Last comamnd active.", 1, asl.size());
EasyMock.verify(mockConnection);
}
/**
* Test of cancelSend method, of class BufferedCommunicator.
*/
@Test
public void testCancelSend() {
System.out.println("cancelSend");
// Queue up 200 characters.
String tenChar = "123456789";
for (int i = 0; i < 20; i++) {
instance.queueStringForComm(tenChar);
}
instance.streamCommands();
// Cancel the send, and clear out the 10 active commands.
instance.cancelSend();
for (int i = 0; i < 10; i++) {
instance.responseMessage("ok");
}
assertEquals(false, instance.areActiveCommands());
}
/**
* Test of responseMessage method, of class BufferedCommunicator.
*/
@Test
public void testResponseMessage() throws Exception {
System.out.println("responseMessage");
String first = "not-handled";
mockScl.rawResponseListener(first);
EasyMock.expect(EasyMock.expectLastCall()).once();
mockScl.rawResponseListener("ok");
EasyMock.expect(EasyMock.expectLastCall()).once();
EasyMock.replay(mockScl);
asl.add(new GcodeCommand("command"));
instance.responseMessage(first);
assertEquals(1, asl.size());
instance.responseMessage("ok");
assertEquals(0, asl.size());
}
/**
* Test of openCommPort method, of class BufferedCommunicator.
*/
@Test
public void testOpenCommPort() throws Exception {
System.out.println("openCommPort");
String name = "";
int baud = 0;
boolean expResult = true;
mockConnection.setCommunicator(EasyMock.<AbstractCommunicator>anyObject());
EasyMock.expect(EasyMock.expectLastCall()).once();
EasyMock.expect(mockConnection.openPort(name, baud)).andReturn(true).once();
EasyMock.replay(mockConnection);
boolean result = instance.openCommPort(name, baud);
assertEquals(expResult, result);
EasyMock.verify(mockConnection);
}
/**
* Test of closeCommPort method, of class BufferedCommunicator.
*/
@Test
public void testCloseCommPort() throws Exception {
System.out.println("closeCommPort");
boolean expResult = true;
mockConnection.closePort();
EasyMock.expect(EasyMock.expectLastCall()).once();
EasyMock.replay(mockConnection);
instance.closeCommPort();
EasyMock.verify(mockConnection);
}
/**
* Test of sendByteImmediately method, of class BufferedCommunicator.
*/
@Test
public void testSendByteImmediately() throws Exception {
System.out.println("sendByteImmediately");
byte b = 10;
String tenChar = "123456789";
for (int i = 0; i < 10; i++) {
mockConnection.sendStringToComm(tenChar + "\n");
}
mockConnection.sendByteImmediately(b);
EasyMock.replay(mockConnection);
// Queue up 200 characters.
for (int i = 0; i < 20; i++) {
instance.queueStringForComm(tenChar);
}
instance.streamCommands();
// Make sure the byte is sent.
instance.sendByteImmediately(b);
EasyMock.verify(mockConnection);
}
/**
* Test of sendingCommand method, of class BufferedCommunicatorImpl.
*/
@Test
public void testSendingCommand() {
System.out.println("sendingCommand");
System.out.println("-N/A for abstract class-");
}
/**
* Test of processedCommand method, of class BufferedCommunicatorImpl.
*/
@Test
public void testProcessedCommand() {
System.out.println("processedCommand");
System.out.println("-N/A for abstract class-");
}
public class BufferedCommunicatorImpl extends BufferedCommunicator {
public int getBufferSize() {
return 101;
}
public void sendingCommand(String command) {
}
public boolean processedCommand(String response) {
return (response != null &&
("ok".equals(response) || response.startsWith("error")));
}
public boolean processedCommandIsError(String response) {
return (response != null && response.startsWith("error"));
}
@Override
public String getLineTerminator() {
return "\r\n";
}
}
}