Google Mock: multiple expectations on same function with different parameters - googletest

Consider the case where a certain mocked function is expected to be called several times, each time with a different value in a certain parameter. I would like to validate that the function was indeed called once and only once per value in a certain list of values (e.g. 1,2,5).
On the other hand, I would like to refrain from defining a sequence as that would dictate a certain order, which is an implementation detail I would like to keep free.
Is there some kind of matcher, or other solution for this case?
I'm not sure if this influences the solution in any way but I do intend to use WillOnce(Return(x)) with a different x per value in the list above.

By default gMock expectations can be satisfied in any order (precisely for the reason you mention -- so you don't over specify your tests).
In your case, you just want something like:
EXPECT_CALL(foo, DoThis(1));
EXPECT_CALL(foo, DoThis(2));
EXPECT_CALL(foo, DoThis(5));
And something like:
foo.DoThis(5);
foo.DoThis(1);
foo.DoThis(2);
Would satisfy those expectations.
(Aside: If you did want to constrain the order, you should use InSequence: https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#expecting-ordered-calls-orderedcalls)

If you expect a function, DoThing, to be called with many different parameters, you can use the following pattern:
for (auto const param : {1, 2, 3, 7, -1, 2}){
EXPECT_CALL(foo, DoThing(param));
}
This is particularly helpful if your EXPECT_CALL includes many parameters, of which only one is changing, or if your EXPECT_CALL includes many Actions to be repeated.

Related

NHibernate QueryOver condition on several properties

I have this armor table, that has three fields to identify individual designs: make, model and version.
I have to implement a search feature for our software, that lets a user search armors according to various criteria, among which their design.
Now, the users' idea of a design is a single string that contains make, model and version concatenated, so the entry is that single string. Let's say they want to look up the specifications for make FH, model TT, version 27, they'll think of (and type) "FHTT27".
We use an IQueryOver object, upon which we add successive conditions according to the criteria. For the design, our code is
z_quoQuery = z_quoQuery.And(armor => armor.make + armor.model + armor.version == z_strDesign);
Which raises an InvalidOperationException, "variable 'armor' of type 'IArmor' referenced from scope '', but it is not defined".
This is described as a bug here: https://github.com/mbdavid/LiteDB/issues/637
After a lot of trial and error, it seems that syntaxs that don't use the armor variable first raise that exception.
Obviously, I have to go another route at least for now, but after searching for some time I can't seem to find how. I thought of using something like
z_quoQuery = z_quoQuery.And(armor => armor.make == z_strDesign.SubString(0, 2).
And(armor => armor.model == z_strDesign.SubString(2, 2).
And(armor => armor.version == z_strDesign.SubString(4, 2);
Unfortunately, the fields are liable to have variable lengths. For instance, another set of values for make, model, and version might be, respectively, "NGI", "928", and "RX", that the code above would parse wrong. So I can't bypass the difficulty that way. Nor can I use a RegEx.
Neither can I make up a property in my Armor class that would concatenate all three properties, since it cannot be converted to SQL by NHibernate.
Has someone an idea of how to do it?
Maybe I should use an explicit SQL condition here, but how would it mix with other conditions?
It seems you can use Projections.Concat to solve your issue:
z_quoQuery = z_quoQuery.And(armor => Projections.Concat(armor.make, armor.model, armor.version) == z_strDesign);

API with an non define number of parameters

I am building an API where I allow the users to passes 2 different list of custom fields.
The API is basically this:
def action(type, name, date, name_custom_1, name_custom_2, name_custom_3, date_custom_1, date_custom_2, date_custom_3, date_custom_4)
So type, name date are parameter of this API and are mandatory.
name_custom_*, and date_custom_* are optionals, I could have 0, 1, 2, 3 ...
I am putting a limit to 3 for name_custom and 4 to date_cutom for technical reasons, but eventually this limit can get increased (but never extremely will never be completely remove)
Now my question is, what is the best way to make this API, from a user point of view:
def action(type, name, date, name_custom_1, name_custom_2, name_custom_3, date_custom_1, date_custom_2, date_custom_3, date_custom_4)
or
def action(type, name, date, names_custom, dates_custom):
Where names_custom and dates_custom are a list which can not be bigger than X.
I am struggling between both and find value and logic in both. Any suggestions?
The list parameters give a cleaner solution, because:
There are less arguments in the function signature, making the documentation easier to read for humans.
It is more resilient to change. Suppose you decide to change the maximum number of custom arguments from 4 to 5. In the list approach, the change is simpler.
Even having 5 arguments in a function call is more than usual, and often considered sloppy (see How many parameters are too many?). You may want to consider introducing a class, or a few classes in here. Depending on your application, maybe it makes sense to create class that encapsulates the name and the list of custom names, and a class that encapsulates the date and the list of custom dates? And perhaps the action itself is better off being a class with a number of setter methods?
In other words, if your functions become long, or argument lists become long, it is often a sign that there are classes waiting to be discovered underneath your design.

[] or () in REST Urls

Has anyone used either [] or () in your REST API urls?
hypothetical examples:
/cars?[colors]:red,[engineType]:13
/cars?(colors):red,(engineType):13
says give me all cars with color red and a certain engine type. Colors is a sub property of the car resource.
Has anyone seen any issues using these to be aware of or is it pretty common to use?
Here's another example. Give me all the cities but only the cities where its people drink coffee
/cities?filter=(people[drinks[type]:6])
or I could even allow more sets as to perform ANDs like this
/cities?filter=(people[drinks[type]:6]),(another layer of filtering)&paging=(offset:10, limit:2)
essentially in the second, the comma itself is an implicit AND for the query because () denotes a filtering criteria so we have one filtering criteria, comma, second filtering criteria so this could easily be wired up to SQL via () and () if you think about it when parsing the url values out of the request and passing it down to a query in the backend.
this is an idea I have.
() - denotes one filter level, adding multiple () are multiple filters
[] - denotes a sub property of a resource
so the above allows the caller to say give me a list of cities but only those whos people like to drink coffee (type 6).
There isn't really an official specification of REST, but this is very unusual. The normal way to do this is to urlencode your parameters in key=value form. Almost all libraries are going to help you do that. You'd have to hand-parse this custom format you've invented (and you need to figure out any escaping issues; what if , or [ can be part of the string? It's unclear what the brackets are getting you in any case.
A more usual way to approach this would be:
/cars?color=red&engineType=13
There are 2 frequent patterns I met so far:
/cars/?colors=red&engineType=13
/cars/colors:red/engineType:13/
Using [] or () in URIs is not common. I don't think you'll have any issues by using them if that's what you desire. Just don't use {} if you want to use URI templates too.

How to avoid having to numerically identify each block in the experiment element in Inquisit?

I often code a study in Inquisit where the study involves running a sequence of blocks. I express the order of the blocks in the form 1=..., 2=..., etc. See the example below.
<expt foostudy>
/blocks=[1=demographics; 2=cogtask; 3=spatialtask]
</expt>
However, it is a hassle when you have many blocks, and you want to add a block in the middle. All the numbers need to be updated.
Is there a way to not have to specify the numbers (e.g., 1, 2, 3) and just let the block order be implied from the sequence they are written?
E.g., Although the following does not work, I'm interested in something like:
<expt foostudy>
/blocks=[demographics; cogtask; spatialtask]
</expt>
It is possible to use the sequence(...) command. I.e., write 1=sequence(...) and place the ordered list of block names between the parentheses separated by commas.
So for the example it would be:
<expt foostudy>
/blocks=[1=sequence(demographics, cogtask, spatialtask)]
</expt>

can a variable have multiple values

In algebra if I make the statement x + y = 3, the variables I used will hold the values either 2 and 1 or 1 and 2. I know that assignment in programming is not the same thing, but I got to wondering. If I wanted to represent the value of, say, a quantumly weird particle, I would want my variable to have two values at the same time and to have it resolve into one or the other later. Or maybe I'm just dreaming?
Is it possible to say something like i = 3 or 2;?
This is one of the features planned for Perl 6 (junctions), with syntax that should look like my $a = 1|2|3;
If ever implemented, it would work intuitively, like $a==1 being true at the same time as $a==2. Also, for example, $a+1 would give you a value of 2|3|4.
This feature is actually available in Perl5 as well through Perl6::Junction and Quantum::Superpositions modules, but without the syntax sugar (through 'functions' all and any).
At least for comparison (b < any(1,2,3)) it was also available in Microsoft Cω experimental language, however it was not documented anywhere (I just tried it when I was looking at Cω and it just worked).
You can't do this with native types, but there's nothing stopping you from creating a variable object (presuming you are using an OO language) which has a range of values or even a probability density function rather than an actual value.
You will also need to define all the mathematical operators between your variables and your variables and native scalars. Same goes for the equality and assignment operators.
numpy arrays do something similar for vectors and matrices.
That's also the kind of thing you can do in Prolog. You define rules that constraint your variables and then let Prolog resolve them ...
It takes some time to get used to it, but it is wonderful for certain problems once you know how to use it ...
Damien Conways Quantum::Superpositions might do what you want,
https://metacpan.org/pod/Quantum::Superpositions
You might need your crack-pipe however.
What you're asking seems to be how to implement a Fuzzy Logic system. These have been around for some time and you can undoubtedly pick up a library for the common programming languages quite easily.
You could use a struct and handle the operations manualy. Otherwise, no a variable only has 1 value at a time.
A variable is nothing more than an address into memory. That means a variable describes exactly one place in memory (length depending on the type). So as long as we have no "quantum memory" (and we dont have it, and it doesnt look like we will have it in near future), the answer is a NO.
If you want to program and to modell this behaviour, your way would be to use a an array (with length equal to the number of max. multiple values). With this comes the increased runtime, hence the computations must be done on each of the values (e.g. x+y, must compute with 2 different values x1+y1, x2+y2, x1+y2 and x2+y1).
In Perl , you can .
If you use Scalar::Util , you can have a var take 2 values . One if it's used in string context , and another if it's used in a numerical context .