How to use 2 DataProviders with 2 data types with 1 Factory in overrriding contructor - testng-dataprovider

I have two DataProviders which should set the datas with two data types (long & double) with one factory, but when I run the code the tests take different data types like, double & int.
public class FactoryTest {
#Factory(dataProvider ="doubleData")
public Object[] getArithmeticDoubleFunctions(double firstNumber,double secondNumber)
{
System.out.println(String.format("Generate test for user: %s %s", firstNumber, secondNumber));
return new Object[]{new ArithmeticFunctionsTest(firstNumber,secondNumber)};
}
#Factory(dataProvider ="longData")
public Object[] getArithmeticLongFunctions(long firstNumber1,long secondNumber1)
{
System.out.println(String.format("Generate test for user: %s %s", firstNumber1, secondNumber1));
return new Object[]{new ArithmeticFunctionsTest( firstNumber1,secondNumber1)};
}
}
#DataProvider(name="longData")
public Object[][] arithmeticDoubleData() {
return new Object[][]{{10, 12}, {-1,-1},{-1,23},{0,1},{-1,2}};
}
#DataProvider(name="doubleData")
public Object[][] arithmeticLongData() {
return new Object[][]{{10.0, 12.3}, {-1.1,-1},{-1.7,23.2},{0,1.2},{-1.1,2.2}};
}
public ArithmeticFunctionsTest(long firstNumber, long secondNubmer) {
this.firstLongNumber = firstNumber;
this.secondLongNumber = secondNubmer;
}
public ArithmeticFunctionsTest(double firstNumber, double secondNumber) {
this.firstDoubleNumber = firstNumber;
this.secondDoubleNumber = secondNumber;
}
#BeforeClass
public void setUp() {
calculator = new Calculator();
}
#Test
public void testLongSum() {
Assert.assertEquals(calculator.sum(firstLongNumber, secondLongNumber), firstLongNumber + secondLongNumber);
System.out.println(firstLongNumber+" "+secondLongNumber+" Long sum");
}
#Test
public void testDoubleSum() {
Assert.assertEquals(calculator.sum(firstDoubleNumber, secondDoubleNumber), firstDoubleNumber + secondDoubleNumber);
System.out.println(firstDoubleNumber+" "+secondDoubleNumber+"double sum");
}
The test with firstNumber and secondNumber types should have only the data providers with needed types, but types are mixing.

public class FactoryTest {
#Factory(dataProvider ="doubleData")
public Object[] getArithmeticDoubleFunctions(double firstNumber,double secondNumber)
{
System.out.println(String.format("Generate test for user: %s %s", firstNumber, secondNumber));
return new Object[]{new ArithmeticFunctionsTest(firstNumber,secondNumber)};
}
#Factory(dataProvider ="longData")
public Object[] getArithmeticLongFunctions(long firstNumber1,long secondNumber1)
{
System.out.println(String.format("Generate test for user: %s %s", firstNumber1, secondNumber1));
return new Object[]{new ArithmeticFunctionsTest( firstNumber1,secondNumber1)};
}
#DataProvider(name="longData")
public Object[][] arithmeticDoubleData() {
return new Object[][]{{10, 12}, {-1,-1},{-1,23},{0,1},{-1,2}};
}
#DataProvider(name="doubleData")
public Object[][] arithmeticLongData() {
return new Object[][]{{10.0, 12.3}, {-1.1,-1},{-1.7,23.2},{0,1.2},{-1.1,2.2}};
}

Related

How can I mock RabbitMQClient of io.quarkiverse.rabbitmqclient.RabbitMQClient and write junit for basic send and consume operation?

I'm new to the quarkus framework where I'm writing rabbitmq-client library based on quarkur framework. I'm using io.quarkiverse.rabbitmqclient.RabbitMQClient.
I need to write JUnit for basic send and consume operations, please help me with how can I write junit and mock RabbitMQClient. I'm using the below code to send and consume message.
#ApplicationScoped
public class RabbitMQProducerAdapterImpl extends RabbitMQCongiguration implements RabbitMQProducerAdapter {
#Override
public void sendMessage(String exchange, String routingKey, String messagePayload) throws IOException {
setUpConnectionAndChannel();
channel.basicPublish(exchange, routingKey, null, messagePayload.getBytes(StandardCharsets.UTF_8));
Log.info("message sent succefully: " + messagePayload);
}
}
Here is the RabbitMQCongiguration
#ApplicationScoped
public class RabbitMQCongiguration {
#Inject
private RabbitMQClient rabbitClient;
protected Channel channel;
protected void setUpConnectionAndChannel() {
try {
// create a connection
Connection connection = rabbitClient.connect();
// create a channel
channel = connection.createChannel();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
protected void setupQueueInDirectExchange(String exchangeName, String routingKey, String queueName,
boolean createExchangeQueues) throws IOException {
setUpConnectionAndChannel();
if (createExchangeQueues) {
this.channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, false, null);
// declaring a queue for this channel. If queue does not exist,
// it will be created on the server. this line not needed if queue already
// present
this.channel.queueDeclare(queueName, true, false, false, null);
}
// Bind Routing Key to Exchange
this.channel.queueBind(queueName, exchangeName, routingKey);
}
}
Below is the class for consumer
#ApplicationScoped
public class RabbitMQConsumerAdapterImpl extends RabbitMQCongiguration implements RabbitMQConsumerAdapter, Runnable {
private String queueName;
private MessageProcessor messageProcessor;
#Override
public void consumeMessage(String exchange, String queueName, String routingKey,
MessageProcessor messageProcessor) throws IOException {
Log.info("starting consumer...");
try {
this.queueName = queueName;
this.messageProcessor = messageProcessor;
Log.info("setting up rabbitMQPrefetchCountConfig");
setupQueueInDirectExchange(exchange, routingKey, queueName, false);
Thread consumerThread = new Thread(this);
consumerThread.start();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
#Override
public void run() {
try {
// start consuming messages. Auto acknowledge messages.
Log.info("Start consuming messages from thread...");
channel.basicConsume(this.queueName, false, (Consumer) new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String msgPayload = null;
if (body == null || body.length == 0) {
Log.warn("Invalid Message Body - Consumer Tag : " + consumerTag + ", Message DeliveryTag : "
+ envelope.getDeliveryTag());
channel.basicReject(envelope.getDeliveryTag(), false);
} else {
msgPayload = new String(body);
try {
JsonParser.parseString(msgPayload);
} catch (JsonSyntaxException ex) {
Log.error(msgPayload + " is not a valid json, Reason - ", ex);
channel.basicReject(envelope.getDeliveryTag(), false);
Log.warn("Rejected the current payload.");
return;
}
messageProcessor.processMessage(msgPayload);
channel.basicAck(envelope.getDeliveryTag(), false);
}
// just print the received message.
Log.info("Received: " + new String(body, StandardCharsets.UTF_8));
}
});
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
#ApplicationScoped
public class MessageProcessorImpl implements MessageProcessor{
#Override
public void processMessage(String messagePayload) {
Log.info("message consumed: " + messagePayload);
}
}

KiteWorks API using HttpWebRequest and MultipartFormDataContent

jsonWebClient.DataContent = new System.Net.Http.MultipartFormDataContent();
ByteArrayContent bytes = new ByteArrayContent(File.ReadAllBytes(data.LocalFile));
bytes.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
jsonWebClient.DataContent.Add(bytes, "file", data.FileName);
jsonWebClient.DataContent.Add(bytes, "name", data.FileName);
jsonWebClient.DataContent.Add(new StringContent($"{Connection.UserId}"), "userId");
jsonWebClient.DataContent.Add(new StringContent($"{data.ParentId}"), "parentId");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.CreationTime}"), "created");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.LastWriteTime}"), "modified");
jsonWebClient.DataContent.Add(new StringContent($"{DateTime.Now}"), "clientCreated");
jsonWebClient.DataContent.Add(new StringContent($"{DateTime.Now}"), "clientModified");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.Length}"), "size");
So I am trying generate a MultipartFormDataContent to convert to a Byte Array or stream. When I do the stream:
Stream stream = _dataContent.ReadAsStreamAsync().Result;
I get a out of memory exception.
When I try to do:
byte[] bytes = _dataContent.ReadAsByteArrayAsync().Result;
or
byte[] bytes = _dataContent.ReadAsByteArrayAsync().GetAwaiter().GetResult();
It just sits there forever and does nothing. What can I do to make it convert to the proper byte array?
Original source [How would I run an async Task method synchronously?][Rachel]How would I run an async Task<T> method synchronously? method-synchronously
public static class AsyncHelpers
{
/// <summary>
/// Execute's an async Task<T> method which has a void return value synchronously
/// </summary>
/// <param name="task">Task<T> method to execute</param>
public static void RunSync(Func<Task> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
synch.Post(async _ =>
{
try
{
await task();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
}
/// <summary>
/// Execute's an async Task<T> method which has a T return type synchronously
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="task">Task<T> method to execute</param>
/// <returns></returns>
public static T RunSync<T>(Func<Task<T>> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
T ret = default(T);
synch.Post(async _ =>
{
try
{
ret = await task();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
return ret;
}
private class ExclusiveSynchronizationContext : SynchronizationContext
{
private bool done;
public Exception InnerException { get; set; }
readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false);
readonly Queue<Tuple<SendOrPostCallback, object>> items =
new Queue<Tuple<SendOrPostCallback, object>>();
public override void Send(SendOrPostCallback d, object state)
{
throw new NotSupportedException("We cannot send to our same thread");
}
public override void Post(SendOrPostCallback d, object state)
{
lock (items)
{
items.Enqueue(Tuple.Create(d, state));
}
workItemsWaiting.Set();
}
public void EndMessageLoop()
{
Post(_ => done = true, null);
}
public void BeginMessageLoop()
{
while (!done)
{
Tuple<SendOrPostCallback, object> task = null;
lock (items)
{
if (items.Count > 0)
{
task = items.Dequeue();
}
}
if (task != null)
{
task.Item1(task.Item2);
if (InnerException != null) // the method threw an exeption
{
throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException);
}
}
else
{
workItemsWaiting.WaitOne();
}
}
}
public override SynchronizationContext CreateCopy()
{
return this;
}
}
}
With this class I was able to convert it right away without waiting and there was no issues with Out of Memory Exception.

write regex in JsonFormat pattern

#JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd'T'HH:mm:ss.SSS")
is it possible to write regex in pattern? I could not
pattern ="yyyy-MM-dd'T'HH:mm:ss.SSS(Z?)"
I want to make Z as optional
any links suggestions?
I ended up creating custom deserializer based on LocalDateDeserializer.INSTANCE and moved the regex there.
After registering the deserializer the object mapper as a custom module the #JsonFormat annotation is no longer required:
#Bean
public ObjectMapper createObjectMapper() {
return new ObjectMapper()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.registerModule(new JavaTimeModule())
.registerModule(new CustomTimeModule());
}
and defined the deserializer in the CustomTimeModule
class CustomTimeModule extends SimpleModule {
public CustomTimeModule() {
super();
addDeserializer(LocalDate.class, CustomLocalDateDeserializer.INSTANCE);
}
}
and finally the regex part, in my case was cutting of the optional non-standard time zone that i was sometimes getting after the date, but could be easily extended to match your case:
public class CustomLocalDateDeserializer extends JSR310DateTimeDeserializerBase<LocalDate> {
private static final long serialVersionUID = 1L;
private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE;
public static final CustomLocalDateDeserializer INSTANCE = new CustomLocalDateDeserializer();
private CustomLocalDateDeserializer() {
this(DEFAULT_FORMATTER);
}
public CustomLocalDateDeserializer(DateTimeFormatter dtf) {
super(LocalDate.class, dtf);
}
#Override
protected JsonDeserializer<LocalDate> withDateFormat(DateTimeFormatter dtf) {
return new CustomLocalDateDeserializer(dtf);
}
#Override
public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
if (parser.hasToken(JsonToken.VALUE_STRING)) {
String string = parser.getText().trim();
if (string.length() == 0) {
return null;
}
// >>>>>>> regex part comes here <<<<<<<
string = parser.getText().trim().substring(0, 10);
// >>>>>>> regex part comes here <<<<<<<
// as per [datatype-jsr310#37], only check for optional (and, incorrect...) time marker 'T'
// if we are using default formatter
try {
return LocalDate.parse(string, _formatter);
} catch (DateTimeException e) {
return _handleDateTimeException(context, e, string);
}
}
if (parser.isExpectedStartArrayToken()) {
JsonToken t = parser.nextToken();
if (t == JsonToken.END_ARRAY) {
return null;
}
if (context.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)
&& (t == JsonToken.VALUE_STRING || t==JsonToken.VALUE_EMBEDDED_OBJECT)) {
final LocalDate parsed = deserialize(parser, context);
if (parser.nextToken() != JsonToken.END_ARRAY) {
handleMissingEndArrayForSingle(parser, context);
}
return parsed;
}
if (t == JsonToken.VALUE_NUMBER_INT) {
int year = parser.getIntValue();
int month = parser.nextIntValue(-1);
int day = parser.nextIntValue(-1);
if (parser.nextToken() != JsonToken.END_ARRAY) {
throw context.wrongTokenException(parser, handledType(), JsonToken.END_ARRAY,
"Expected array to end");
}
return LocalDate.of(year, month, day);
}
context.reportInputMismatch(handledType(),
"Unexpected token (%s) within Array, expected VALUE_NUMBER_INT",
t);
}
if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) {
return (LocalDate) parser.getEmbeddedObject();
}
// 06-Jan-2018, tatu: Is this actually safe? Do users expect such coercion?
if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
return LocalDate.ofEpochDay(parser.getLongValue());
}
return _handleUnexpectedToken(context, parser, "Expected array or string.");
}

rxjava - How to handle merge exceptions without terminating the whole process

I have created two observables.
One of them throws an exception.
obs1 = Observable.from(new Integer[]{1, 2, 3, 4, 5, 6});
obs2 = Observable.create(new Observable.OnSubscribe<Integer>() {
#Override public void call(Subscriber<? super Integer> subscriber) {
boolean b = getObj().equals(""); // this throws an exception
System.out.println("1");
}
});
Now I invoke them using
Observable.merge(obs2, obs1)
.subscribe(new Observer<Integer>() {
#Override public void onCompleted() {
System.out.println("onCompleted");
}
#Override public void onError(Throwable throwable) {
System.out.println("onError");
}
#Override public void onNext(Integer integer) {
System.out.println("onNext - " + integer);
}
});
Now, I dont want my process to halt completely when an exception occurs -
I want to handle it and I want obs1 to continue its work.
I have tried to write it using onErrorResumeNext(), onExceptionResumeNext(), doOnError()
but nothing helped - obs1 did not run.
How can I handle the exception without stopping the other observable from being processed?
Sounds like you need mergeDelayError.
The problem is in your subscriber which is broken. You should catch your exception and call onError. Otherwise, you broke the rx contract.
example :
Observable<Integer> obs1 = Observable.from(Arrays.asList(1, 2, 3, 4, 5, 6));
Observable<Integer> obs2 = Observable.create((Subscriber<? super Integer> subscriber) -> {
subscriber.onError(new NullPointerException());
});
Observable.merge(obs2.onErrorResumeNext((e) -> Observable.empty()), obs1)
.subscribe(new Observer<Integer>() {
#Override public void onCompleted() {
System.out.println("onCompleted");
}
#Override public void onError(Throwable throwable) {
System.out.println("onError");
}
#Override public void onNext(Integer integer) {
System.out.println("onNext - " + integer);
}
});
so if you replace your obs2 code with this, it should work like you expected :
obs2 = Observable.create(new Observable.OnSubscribe<Integer>() {
#Override public void call(Subscriber<? super Integer> subscriber) {
try {
boolean b = getObj().equals(""); // this throws an exception
System.out.println("1");
} catch(Exception ex) {
subscriber.onError(ex);
}
}
});

How to know what text has been deleted from a JTextPane

I have added a document listener to a JTextPane. I want to know what text has been added or removed so I can take action if certain key words are entered. The insert part works just fine, but I do not know how to detect what text was deleted.
The insert works because the text is there and I can select it, but the delete has already removed the text so I get bad location exceptions sometimes.
I want to make reserved words that are not inside quotes bold so I need to know what has been removed, removing even one character (like a quote) could have a huge impact.
My code follows:
#Override
public void insertUpdate(DocumentEvent e)
{
Document doc = e.getDocument();
String i = "";
try
{
i = doc.getText(e.getOffset(), e.getLength());
}
catch(BadLocationException e1)
{
e1.printStackTrace();
}
System.out.println("INSERT:" + e + ":" + i);
}
#Override
public void removeUpdate(DocumentEvent e)
{
Document doc = e.getDocument();
String i = "";
try
{
i = doc.getText(e.getOffset(), e.getLength());
}
catch(BadLocationException e1)
{
e1.printStackTrace();
}
System.out.println("REMOVE:" + e + ":" + i);
}
This is strange that there is no simple way to get this information.
I've looked at the source code of Swing libraries for this. Of course - there is this information in DocumentEvent, which is of class AbstractDocument$DefaultDocumentEvent, which contains protected Vector<UndoableEdit> edits, which contains one element of type GapContent$RemoveUndo, which contains protected String string that is used only in this class (no other "package" classes get this) and this RemoveUndo class have no getter for this field.
Even toString didn't show it (because RemoveUndo hasn't overrided toString method):
[javax.swing.text.GapContent$RemoveUndo#6303ddfd hasBeenDone: true alive: true]
This is so strange for me that I belive that there is some other easy way to get the removed string and that I just don't know how to accomplish it.
One thing you can do is the most obvious:
final JTextArea textArea = new JTextArea();
textArea.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
previousText = textArea.getText();
}
});
textArea.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
if(previousText != null) {
String removedStr = previousText.substring(e.getOffset(), e.getOffset() + e.getLength());
System.out.println(removedStr);
}
}
#Override
public void insertUpdate(DocumentEvent e) {
}
#Override
public void changedUpdate(DocumentEvent e) {
}
});
where previousText is an instance variable.
or (the most nasty ever):
textArea.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
String removedString = getRemovedString(e);
System.out.println(removedString);
}
#Override
public void insertUpdate(DocumentEvent e) {
}
#Override
public void changedUpdate(DocumentEvent e) {
}
});
plus this method:
public static String getRemovedString(DocumentEvent e) {
try {
Field editsField = null;
Field[] fields = CompoundEdit.class.getDeclaredFields();
for(Field f : fields) {
if(f.getName().equals("edits")) {
editsField = f;
break;
}
}
editsField.setAccessible(true);
List edits = (List) editsField.get(e);
if(edits.size() != 1) {
return null;
}
Class<?> removeUndo = null;
for(Class<?> c : GapContent.class.getDeclaredClasses()) {
if(c.getSimpleName().equals("RemoveUndo")) {
removeUndo = c;
break;
}
}
Object removeUndoInstance = edits.get(0);
fields = removeUndo.getDeclaredFields();
Field stringField = null;
for(Field f : fields) {
if(f.getName().equals("string")) {
stringField = f;
break;
}
}
stringField.setAccessible(true);
return (String) stringField.get(removeUndoInstance);
}
catch(SecurityException e1) {
e1.printStackTrace();
}
catch(IllegalArgumentException e1) {
e1.printStackTrace();
}
catch(IllegalAccessException e1) {
e1.printStackTrace();
}
return null;
}
I had the same problem than you. And what Xeon explained help me a lot too. But after, i found a way to do that. In my case, i created a custom StyledDocument class that extends DefaultStyledDocument:
public class CustomStyledDocument extends DefaultStyledDocument
{
public CustomStyledDocument () {
super();
}
#Override
public void insertString(int offset, String string, AttributeSet as) throws BadLocationException {
super.insertString(offset, string, as);
}
#Override
public void remove(int offset, int i1) throws BadLocationException {
String previousText = getText(offset, i1);
super.remove(offset, i1);
}
}
So if you call getText method before you call super.remove(...), you will get the previous text.