Can I avoid casting when testing a Supplier of Streams - assertj

When using AssertJ, can I avoid casting when testing a Supplier of Streams?
I tried looking at open issues and most point to https://github.com/joel-costigliola/assertj-core/issues/683 but I don't think it is a direct match.
Supplier<Stream<String>> supplier =
() -> Stream.of("String1", "String2");
assertThat(supplier).isNotNull()
.extracting(Supplier::get)
.isInstanceOf(Stream.class)
.satisfies((stream) ->
assertThat((Stream)stream)
.contains("String1", "String2"));
The test works but I would like to avoid the casting of the Stream if possible.
Thanks.

I agree with tkruse comment!
I just want to add that in AssertJ Core next version (3.13.0), you will be able to use asInstanceOf to cast the object under test and access type specific assertion, see https://github.com/joel-costigliola/assertj-core/pull/1498
Object value = 0;
assertThat(values).asInstanceOf(INTEGER).isZero();
In your case, I believe you would be able to write:
assertThat(supplier).isNotNull()
.extracting(Supplier::get)
.asInstanceOf(STREAM)
.satisfies(stream -> assertThat(stream).contains("String1",
"String2"));

Related

Replacement for deprecated PostgresDataType.JSON?

I'm using JOOQ with PostgreSQL, and trying to implement a query like this:
INSERT INTO dest_table (id,name,custom_data)
SELECT key as id,
nameproperty as name,
CONCAT('{"propertyA": "',property_a,'", "propertyB": "',property_b,'","propertyC": "',property_c,'"}')::json as custom_data
FROM source_table
The concatenation/JSON bit is what I'm here to ask about. I actually have managed to get it working, but only by using this (Kotlin):
val concatBits = mutableListOf<Field<Any>>()
... build up various bits of the concatenation ...
val concatField = concat(*(concatBits.toTypedArray())).cast(PostgresDataType.JSON)
It concerns me that PostgresDataType is deprecated. The documentation says I should use SQLDataType instead, but it has no JSON value.
What's the recommended way to do this?
EDIT: a bit more information ...
I'm building the query like this:
val innerSelectFields = listOf(
field("key").`as`(DEST_TABLE.ID),
field("nameproperty").`as`(DEST_TABLE.NAME),
concatField.`as`(DEST_TABLE.CUSTOM_DATA)
)
val innerSelect = dslContext
.select(innerSelectFields)
.from(table("source_table"))
val insertInto = dslContext
.insertInto(DEST_TABLE)
.select(innerSelect)
The initial query I posted is slightly misleading, as the resulting SQL from this code doesn't have the
(id,name,custom_data) part.
Also, in case it matters, "source_table" is a temporary table, created during runtime, so there are no autogenerated classes for it.
jOOQ currently doesn't support the JSON data type out of the box. The main reason is that it is unclear what Java type to bind a JSON data structure to, as the JDK doesn't have such a standard type, and jOOQ will not prefer one third party library over the other.
The currently recommended approach is to create your own custom data type binding for your preferred third party JSON library:
https://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings
In that case, you will no longer need to explicitly cast your bind variable to some JSON type, because your binding will take care of that transparently.

Elastic4s, mockito and verify with type erasure and implicits

In previous versions of Elastic4s you could do something like
val argument1: ArgumentCapture[DeleteIndexDefinition] = ???
verify(client).execute(argument1.capture())
assert(argument1 == ???)
val argument2: ArgumentCapture[IndexDefinition] = ???
verify(client, times(2)).execute(argument2.capture())
assert(argument2 == ???)
after several executions in your test (i.e. one DeleteIndexDefinition, followed of two IndexDefinition). And each verify would be matched against its type.
However, Elastic4s now takes an implicit parameter in its client.execute method. The parameter is of type Executable[T,R], which means you now need something like
val argument1: ArgumentCapture[DeleteIndexDefinition] = ???
verify(client).execute(argument1.capture())(any[Executable[DeleteIndexDefinition,R]])
assert(argument1 == ???)
val argument2: ArgumentCapture[IndexDefinition] = ???
verify(client, times(2)).execute(argument2.capture())(any[Executable[IndexDefinition,R]])
assert(argument2 == ???)
After doing that, I was getting an error. Mockito is considering both three client.execute in the first verify. Yes, even if the first parameter is of a different type.
That's because the implicit(the second parameter) has, after type erasure, the same type Executable.
So the asertions were failing. How to test in this setup?
The approach now taken in elastic4s to encapsulate the logic for executing each request type is one using typeclasses. This is why the implicit now exists. It help modularize each request type, and avoids the God class anti-pattern that was starting to creep into the ElasticClient class.
Two things I can think of that might help you:
What you already posted up, using Mockito and passing in the implicit as another matcher. This is how you can mock a method using implicits in general.
Not use mockito, but spool up a local embedded node, and try it against real data. This is my preferred approach when I write elasticsearch code. The advantages are that you're testing real queries against the real server, so not only checking that they are invoked, but that they actually work. (Some people might consider this an integration test, but whatever I don't agree, it all runs inside a single self contained test with no outside deps).
The latest release of elastic4s even include a testkit that makes it really easy to get the embedded node. You can look at almost any of the unit tests to give you an idea how to use it.
My solution was to create one verify with a generic type. It took me a while to realise that even if there is no common type, you always have AnyRef.
So, something like this works
val objs: ArgumentCaptor[AnyRef] = ArgumentCaptor.forClass(classOf[AnyRef])
verify(client, times(3)).execute(objs.capture())(any())
val values = objs.getAllValues
assert(values.get(0).isInstanceOf[DeleteIndexDefinition])
assert(values.get(1).isInstanceOf[IndexDefinition])
assert(values.get(2).isInstanceOf[IndexDefinition])
I've created both the question and the answer. But I'll consider other answers.

string option to string conversion

How do I convert the string option data type to string in Ocaml?
let function1 data =
match data with
None -> ""
| Some str -> str
Is my implementation error free? Here 'data' has a value of type string option.
To answer your question, yes.
For this simple function, you can easily find it in Option module. For example, Option.default totally fits your purpose:
let get_string data =
Option.default "" data
There are many other useful functions for working with option types in that module, you should check them out to avoid redefine unnecessary functions.
Another point is that the compiler would tell you if there's something wrong. If the compiler doesn't complain, you know that the types all make sense and that you have covered every case in your match expression. The OCaml type system is exceptionally good at finding problems while staying out of your way. Note that you haven't had to define any types yourself in this small example--the compiler will infer that the type of data is string option.
A lot of the problems the compiler can't detect are ones that we can't detect either. We can't tell whether mapping None to the empty string is what you really wanted to do, though it seems very sensible.

How do I read this OCaml type signature?

I'm currently experimenting with using OCaml and GTK together (using the lablgtk bindings). However, the documentation isn't the best, and while I can work out how to use most of the features, I'm stuck with changing notebook pages (switching to a different tab).
I have found the function that I need to use, but I don't know how to use it. The documentation seems to suggest that it is in a sub-module of GtkPackProps.Notebook, but I don't know how to call this.
Also, this function has a type signature different to any I have seen before.
val switch_page : ([> `notebook ], Gpointer.boxed option -> int -> unit) GtkSignal.t
I think it returns a GtkSignal.t, but I have no idea how to pass the first parameter to the function (the whole part in brackets).
Has anyone got some sample code showing how to change the notebook page, or can perhaps give me some tips on how to do this?
What you have found is not a function but the signal. The functional type you see in its type is the type of the callback that will be called when the page switch happen, but won't cause it.
by the way the type of switch_page is read as: a signal (GtkSignal.t) raised by notebook [> `notebook ], whose callbacks have type Gpointer.boxed option -> int -> unit
Generally speaking, with lablgtk, you'd better stay away of the Gtk* low level modules, and use tge G[A-Z] higher level module. Those module API look like the C Gtk one, and I always use the main Gtk doc to help myself.
In your case you want to use the GPack.notebook object and its goto_page method.
You've found a polymorphic variant; they're described in the manual in Section 4.2, and the typing rules always break my head. I believe what the signature says is that the function switch_page expects as argument a GtkSignal.t, which is an abstraction parameterized by two types:
The first type parameter,
[> `notebook]
includes as values any polymorphic variant including notebook (that's what the greater-than means).
The second type parameter is an ordinary function.
If I'm reading the documentation for GtkSignal.t correctly, it's not a function at all; it's a record with three fields:
name is a string.
classe is a polymorphic variant which could be ``notebook` or something else.
marshaller is a marshaller for the function type Gpointer.boxed option -> int -> unit.
I hope this helps. If you have more trouble, section 4.2 of the manual, on polymorphic variants, might sort you out.

How to workaround the XmlSerialization issue with type name aliases (in .NET)?

I have a collection of objects and for each object I have its type FullName and either its value (as string) or a subtree of inner objects details (again type FullName and value or a subtree).
For each root object I need to create a piece of XML that will be xml de-serializable.
The problem with XmlSerializer is that i.e. following object
int age = 33;
will be serialized to
<int>33</int>
At first this seems to be perfectly ok, however when working with reflection you will be using System.Int32 as type name and int is an alias and this
<System.Int32>33</System.Int32>
will not deserialize.
Now additional complexity comes from the fact that I need to handle any possible data type.
So solutions that utilize System.Activator.CreateInstance(..) and casting won't work unless I go down the path of code gen & compilation as a way of achieving this (which I would rather avoid)
Notes:
A quick research with .NET Reflector revealed that XmlSerializer uses internal class TypeScope, look at its static constructor to see that it initializes an inner HashTable with mappings.
So the question is what is the best (and I mean elegant and solid) way to workaround this sad fact?
I don't exactly see, where your problem originally stems from. XmlSerializer will use the same syntax/mapping for serializing as for deserializing, so there is no conflict when using it for both serializing and deserializing.
Probably the used type-tags are some xml-standard thing, but not sure about that.
I guess the problem is more your usage of reflection. Do you instantiate your
imported/deserialized objects by calling Activator.CreateInstance ?
I would recommend the following instead, if you have some type Foo to be created from the xml in xmlReader:
Foo DeserializedObject = (Foo)Serializer(typeof(Foo)).Deserialize(xmlReader);
Alternatively, if you don't want to switch to the XmlSerializer completely, you could do some preprocessing of your input. The standard way would then be to create some XSLT, in which you transform all those type-elements to their aliases or vice versa. then before processing the XML, you apply your transformation using System.Xml.Xsl.XslCompiledTransform and use your (or the reflector's) mappings for each type.
Why don't you serialize all the field's type as an attribute?
Instead of
<age>
<int>33</int>
</age>
you could do
<age type="System.Int32">
33
</age>