Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GET_FIELD_TESTS #1

Merged
merged 2 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/main/java/net/infordata/em/TerminalClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ public void setFieldTextByLabel(String label, String text) {
*/
public void sendKeyEvent(int keyCode, int modifiers) {
emulator.processRawKeyEvent(
new KeyEvent(emulator, KeyEvent.KEY_PRESSED, 0, modifiers, keyCode, KeyEvent.CHAR_UNDEFINED));
new KeyEvent(emulator, KeyEvent.KEY_PRESSED, 0, modifiers, keyCode,
KeyEvent.CHAR_UNDEFINED));
}

/**
Expand All @@ -181,6 +182,13 @@ public String getScreenText() {
return screen.toString();
}

/**
* Gets the fields present on the current screen.
*
* @return fields of the screen. Take into consideration that this only returns fields that hold
* some information to be sent to the server. The screen is composed by its textual representation
* plus these fields.
*/
public List<XI5250Field> getFields() {
return emulator.getFields();
}
Expand Down
17 changes: 14 additions & 3 deletions src/main/java/net/infordata/em/crt5250/XI5250Field.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,21 @@ protected void processFieldPaintEvent(XI5250FieldPaintEvent e) {
break;
}
}


public int getAttr() {
return ivAttr;
}
public final XI5250Crt getCrt() {
return ivCrt;
}


public byte[] getFFW() {
return ivFFW;
}

public byte[] getFCW() {
return ivFCW;
}
/**
* Initializes the field. It is called after that the 5250 panel construction has ended to let the
* field refresh its color attribute.
Expand Down Expand Up @@ -316,10 +326,11 @@ public void setString(String aStr) {
*
* @return value of the field as String
*/

public String getString() {
return ivCrt.getString(ivCol, ivRow, ivLength);
}

/**
* Returns value of the field as String, all trailing nulls and blanks are cut off. NOTE: signed
* numeric are followed by sign char
Expand Down
218 changes: 178 additions & 40 deletions src/test/java/net/infordata/em/TerminalClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import net.infordata.em.crt5250.XI5250Field;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
Expand All @@ -24,10 +25,13 @@
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Optional;
import java.util.List;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;

public class TerminalClientTest {

Expand All @@ -36,12 +40,6 @@ public class TerminalClientTest {
private static final String SERVICE_HOST = "localhost";
private static final String TERMINAL_TYPE = "IBM-3477-FC";

private VirtualTcpService service = new VirtualTcpService();
private TerminalClient client;
private ExceptionWaiter exceptionWaiter;
private ScheduledExecutorService stableTimeoutExecutor = Executors
.newSingleThreadScheduledExecutor();

@Rule
public TestRule watchman = new TestWatcher() {
@Override
Expand All @@ -54,6 +52,11 @@ public void finished(Description description) {
LOG.debug("Finished {}", description.getMethodName());
}
};
private VirtualTcpService service = new VirtualTcpService();
private TerminalClient client;
private ExceptionWaiter exceptionWaiter;
private ScheduledExecutorService stableTimeoutExecutor = Executors
.newSingleThreadScheduledExecutor();

@Before
public void setup() throws IOException {
Expand All @@ -72,31 +75,6 @@ private String getResourceFilePath(String resourcePath) {
return getClass().getResource(resourcePath).getFile();
}

private static class ExceptionWaiter implements ExceptionHandler {

private CountDownLatch exceptionLatch = new CountDownLatch(1);
private CountDownLatch closeLatch = new CountDownLatch(1);

@Override
public void onException(Throwable ex) {
exceptionLatch.countDown();
}

@Override
public void onConnectionClosed() {
closeLatch.countDown();
}

private void awaitException() throws InterruptedException {
assertThat(exceptionLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

private void awaitClose() throws InterruptedException {
assertThat(closeLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

}

@After
public void teardown() throws Exception {
client.disconnect();
Expand Down Expand Up @@ -153,16 +131,16 @@ private SSLContext buildSslContext() throws GeneralSecurityException {
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager trustManager = new X509TrustManager() {

public java.security.cert.X509Certificate[] getAcceptedIssuers() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}

public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
X509Certificate[] certs, String authType) {
}

public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
X509Certificate[] certs, String authType) {
}
};
sslContext.init(null, new TrustManager[]{trustManager},
Expand Down Expand Up @@ -195,8 +173,8 @@ private void loginByCoord() {
}

private void loginByLabel() {
client.setFieldTextByLabel("User","TESTUSR");
client.setFieldTextByLabel("Password","TESTPSW");
client.setFieldTextByLabel("User", "TESTUSR");
client.setFieldTextByLabel("Password", "TESTPSW");
client.sendKeyEvent(KeyEvent.VK_ENTER, 0);
}

Expand Down Expand Up @@ -264,7 +242,7 @@ public void shouldThrowIllegalArgumentExceptionWhenSendIncorrectFieldPosition()
public void shouldThrowIllegalArgumentExceptionWhenSendIncorrectFieldLabel()
throws Exception {
awaitKeyboardUnlock();
client.setFieldTextByLabel("test","test");
client.setFieldTextByLabel("test", "test");
}

@Test
Expand All @@ -275,19 +253,179 @@ public void shouldSendCloseToExceptionHandlerWhenServerDown() throws Exception {
}

@Test
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByCoord() throws Exception {
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByCoord()
throws Exception {
awaitKeyboardUnlock();
service.stop(TIMEOUT_MILLIS);
loginByCoord();
exceptionWaiter.awaitException();
}

@Test
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByLabel() throws Exception {
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByLabel()
throws Exception {
awaitKeyboardUnlock();
service.stop(TIMEOUT_MILLIS);
loginByLabel();
exceptionWaiter.awaitException();
}

@Test
public void shouldGetCorrectFieldsWhenGetFields() throws Exception {
awaitKeyboardUnlock();
List<TestField> actualFields = client.getFields().stream()
.map(TestField::new)
.collect(Collectors.toList());
assertEquals(buildExpectedFields(), actualFields);
}

private List<TestField> buildExpectedFields() {
List<TestField> testFieldList = new ArrayList<>();
int fieldsColumn = 52;
String fieldsText = "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000";
testFieldList.add(new TestField.Builder(5, fieldsColumn, fieldsText).withMonocase().build());
testFieldList.add(
new TestField.Builder(6, fieldsColumn, fieldsText).withMonocase().withHighIntensity()
.withReverseImage()
.build());
testFieldList.add(new TestField.Builder(7, fieldsColumn, fieldsText).build());
testFieldList.add(new TestField.Builder(8, fieldsColumn, fieldsText).build());
testFieldList.add(new TestField.Builder(9, fieldsColumn, fieldsText).build());
return testFieldList;
}

private static class TestField {

private static final byte FIELD_FORMAT_MASK = 0x40;
private static final byte MONOCASE_MASK = 0x20;
private static final byte SCREEN_ATTRIBUTE_MASK = 0x20;
private static final byte UNDERSCORE_MASK = 0x04;
private static final byte HIGH_INTENSITY_MASK = 0x02;
private static final byte REVERSE_IMAGE_MASK = 0x01;

private final int row;
private final int column;
private final String text;
private final byte[] ffw;
private final byte[] fcw;
private final int attr;

private TestField(Builder builder) {
row = builder.row;
column = builder.column;
attr = builder.attr;
text = builder.text;
ffw = builder.ffw;
fcw = builder.fcw;
}

private TestField(XI5250Field field) {
column = field.getCol();
row = field.getRow();
attr = field.getAttr();
text = field.getString();
ffw = field.getFFW();
fcw = field.getFCW();
}

private static final class Builder {

private final int row;
private final int column;
private final String text;
private final byte[] fcw = {0, 0};
private byte[] ffw = {FIELD_FORMAT_MASK, 0};
private byte attr = SCREEN_ATTRIBUTE_MASK | UNDERSCORE_MASK;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary new line :-)

private Builder(int row, int column, String text) {
this.row = row;
this.column = column;
this.text = text;
}

private Builder withMonocase() {
ffw[1] |= MONOCASE_MASK;
return this;
}

private Builder withHighIntensity() {
attr |= HIGH_INTENSITY_MASK;
return this;
}

private Builder withReverseImage() {
attr |= REVERSE_IMAGE_MASK;
return this;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary new lines

private TestField build() {
return new TestField(this);
}

}

@Override
public String toString() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing spacing between methods

return "TestField{" +
"row=" + row +
", column=" + column +
", ffw=" + Arrays.toString(ffw) +
", fcw=" + Arrays.toString(fcw) +
", attr=" + attr +
", text='" + text + '\'' +
'}';
}

@Override

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing spacing between methods

public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TestField testField = (TestField) o;
return row == testField.row &&
column == testField.column &&
attr == testField.attr &&
Arrays.equals(ffw, testField.ffw) &&
Arrays.equals(fcw, testField.fcw) &&
Objects.equals(text, testField.text);
}

@Override
public int hashCode() {
int result = Objects.hash(row, column, attr, text);
result = 31 * result + Arrays.hashCode(ffw);
result = 31 * result + Arrays.hashCode(fcw);
return result;
}

}

private static class ExceptionWaiter implements ExceptionHandler {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing spacing between classes


private CountDownLatch exceptionLatch = new CountDownLatch(1);
private CountDownLatch closeLatch = new CountDownLatch(1);

@Override
public void onException(Throwable ex) {
exceptionLatch.countDown();
}

@Override
public void onConnectionClosed() {
closeLatch.countDown();
}

private void awaitException() throws InterruptedException {
assertThat(exceptionLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

private void awaitClose() throws InterruptedException {
assertThat(closeLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

}

}