Doing CallOrder of Fake on itself with argument validation - sinon

How do i do a call order verification of a fake with argument validation in sinon.js?
It is the same fake which is called multiple times with different arguments...
something like below
let someFake = sinon.fake();
someFake(1);
someFake(2);
someFake(3);
sinon.assert.callOrder(someFake.calledWith(1), someFake.calledWith(2),
someFake.calledWith(3));

You are essentially using the wrong API for the job, so it's no wonder you are not getting the expected results :) If you look at the docs for callOrder you will see that the signature is using spy1, spy2, .., which indicates that it is meant to be used by more than one spy. A fake is implementation wise also a Spy, so all bits of the Spy API also applies to a Fake. From the docs:
The created fake Function, with or without behavior has the same API as a sinon.spy
A sidenode, that is a bit confusing, is that the docs often use the term "fake" to apply to any fake object or function, not functions created using the sinon.fake API specifically, although, that should not be an issue in this particular case.
With regards to your original question, the Spy API has got you covered since Sinon 1.0 here. You use getCall(n) to return the nth call. There are lots of interactive examples in the docs for this, but essentially you just do this:
// dumbed down version of https://runkit.com/fatso83/stackoverflow-66192966
const fake = sinon.fake();
fake(1);
fake(20);
fake(300);
sinon.assert.calledThrice(fake);
assertEquals(1, fake.getCall(0).args[0])
assertEquals(20, fake.secondCall.args[0])
assertEquals(300, fake.lastCall.args[0])
function assertEquals(arg1,arg2){
if(arg1 !== arg2) {
throw new Error(`Expected ${arg1} to equal ${arg2}`);
}
console.log(`${arg1} equal ${arg2}: OK`)
}
<script src="https://cdn.jsdelivr.net/npm/sinon#latest/pkg/sinon.js"></script>

Related

OpenMDAO Optional Error on Unconnected Input

Is there any way to force OpenMDAO to raise an error if a given input is unconnected? I know for many inputs, defaults can be provided such that the input doesn't need to be connected, however is there a way to tell OpenMDAO to automatically raise an error if certain key inputs are unconnected?
This is not built into OpenMDAO, as of V3.17. However, it is possible to do it. The only caveat is that i had to use some non public APIs to make it work (notice the use of the p.model._conn_global_abs_in2out). So those APIs are subject to changer later.
This code should give you the behavior your want. You could augment things with the use of variable tagging if you wanted a solution that didn't require you to give a list of variable names to the validate function. The list_inputs method can accept tags to filter by instead if you prefer that.
import openmdao.api as om
def validate_connections(prob, force_connected):
# make sure its a set and not a generic iterator (i.e. array)
force_connected_set = set(force_connected)
model_inputs = prob.model.list_inputs(out_stream=None, prom_name=True)
#gets the promoted names from the list of inputs
input_set = set([inp[1]['prom_name'] for inp in model_inputs])
# filter the inputs into connected and unconnected sets
connect_dict = p.model._conn_global_abs_in2out
unconnected_inputs = set()
connected_inputs = set()
for abs_name, in_data in model_inputs:
if abs_name in connect_dict and (not 'auto_ivc' in connect_dict[abs_name]):
connected_inputs.add(in_data['prom_name'])
else:
unconnected_inputs.add(in_data['prom_name'])
# now we need to check if there are any unconnected inputs
# in the model that aren't in the spec
illegal_unconnected = force_connected_set.intersection(unconnected_inputs)
if len(illegal_unconnected) > 0:
raise ValueError(f'unconnected inputs {illegal_unconnected} are are not allowed')
p = om.Problem()
###############################################################################################
# comment and uncomment these three lines to change the error you get from the validate method
###############################################################################################
# p.model.add_subsystem('c0', om.ExecComp('x=3*a'), promotes_outputs=['x'])
# p.model.add_subsystem('c1', om.ExecComp('b=a+17'))
# p.model.connect('c1.b', 'c2.b')
p.model.add_subsystem('c2', om.ExecComp('y=2*x+b'), promotes_inputs=['x'])
p.model.add_subsystem('c3', om.ExecComp('z=x**2+y'))
p.setup()
p.final_setup()
If this is a feature you think should be added to OpenMDAO proper, then feel free to submit a POEM proposing how a formal feature and its API might look.

how to get list of Auto-IVC component output names

I'm switching over to using the Auto-IVC component as opposed to the IndepVar component. I'd like to be able to get a list of the promoted output names of the Auto-IVC component, so I can then use them to go and pull the appropriate value out of a configuration file and set the values that way. This will get rid of some boilerplate.
p.model._auto_ivc.list_outputs()
returns an empty list. It seems that p.model__dict__ has this information encoded in it, but I don't know exactly what is going on there so I am wondering if there is an easier way to do it.
To avoid confusion from future readers, I assume you meant that you wanted the promoted input names for the variables connected to the auto_ivc outputs.
We don't have a built-in function to do this, but you could do it with a bit of code like this:
seen = set()
for n in p.model._inputs:
src = p.model.get_source(n)
if src.startswith('_auto_ivc.') and src not in seen:
print(src, p.model._var_allprocs_abs2prom['input'][n])
seen.add(src)
assuming 'p' is the name of your Problem instance.
The code above just prints each auto_ivc output name followed by the promoted input it's connected to.
Here's an example of the output when run on one of our simple test cases:
_auto_ivc.v0 par.x

Use input variable in assert or specify the data to assert

I have a unit test for a function that adds data (untransformed) to the database. The data to insert is given to the create function.
Do I use the input data in my asserts or is it better to specify the data that I’m asserting?
For eample:
$personRequest = [
'name'=>'John',
'age'=>21,
];
$id = savePerson($personRequest);
$personFromDb = getPersonById($id);
$this->assertEquals($personRequest['name'], $personFromDb['name']);
$this->assertEquals($personRequest['age'], $personFromDb['age']);
Or
$id = savePerson([
'name'=>'John',
'age'=>21,
]);
$personFromDb = getPersonById($id);
$this->assertEquals('John', $personFromDb['name']);
$this->assertEquals(21, $personFromDb['age']);
I think 1st option is better. Your input data may change in future and if you go by 2nd option, you will have to change assertion data everytime.
2nd option is useful, when your output is going to be same irrespective of your input data.
I got an answer from Adam Wathan by e-mail. (i took his test driven laravel course and noticed he uses the 'specify' option)
I think it's just personal preference, I like to be able to visually
skim and see "ok this specific string appears here in the output and
here in the input", vs. trying to avoid duplication by storing things
in variables." Nothing wrong with either approach in my opinion!
So i can't choose a correct answer.

Creating graph in titan from data in csv - example wiki.Vote gives error

I am new to Titan - I loaded titan and successfully ran GraphOfTheGods example including queries given. Next I went on to try bulk loading csv file to create graph and followed steps in Powers of ten - Part 1 http://thinkaurelius.com/2014/05/29/powers-of-ten-part-i/
I am getting an error in loading wiki-Vote.txt
gremlin> g = TitanFactory.open("/tmp/1m") Backend shorthand unknown: /tmp/1m
I tried:
g = TitanFactory.open('conf/titan-berkeleydb-es.properties’)
but get an error in the next step in load-1m.groovy
==>titangraph[berkeleyje:/titan-0.5.4-hadoop2/conf/../db/berkeley] No signature of method: groovy.lang.MissingMethodException.makeKey() is applicable for argument types: () values: [] Possible solutions: every(), any()
Any hints what to do next? I am using groovy for the first time. what kind of groovy expertise needed for working with gremlin
That blog post is meant for Titan 0.4.x. The API shifted when Titan went to 0.5.x. The same principles discussed in the posts generally apply to data loading but the syntax is different in places. The intention is to update those posts in some form when Titan 1.0 comes out with full support of TinkerPop3. Until then, you will need to convert those code examples to the revised API.
For example, an easy way to create a berkeleydb database is with:
g = TitanFactory.build()
.set("storage.backend", "berkeleyje")
.set("storage.directory", "/tmp/1m")
.open();
Please see the docs here. Then most of the schema creation code (which is the biggest change) is now described here and here.
After much experimenting today, I finally figured it out. A lot of changes were needed:
Use makePropertyKey() instead of makeKey(), and makeEdgeLabel() instead of makeLabel()
Use cardinality(Cardinality.SINGLE) instead of unique()
Building the index is quite a bit more complicated. Use the management system instead of the graph both to make the keys and labels, as well as build the index (see https://groups.google.com/forum/#!topic/aureliusgraphs/lGA3Ye4RI5E)
For posterity, here's the modified script that should work (as of 0.5.4):
g = TitanFactory.build().set("storage.backend", "berkeleyje").set("storage.directory", "/tmp/1m").open()
m = g.getManagementSystem()
k = m.makePropertyKey('userId').dataType(String.class).cardinality(Cardinality.SINGLE).make()
m.buildIndex('byId', Vertex.class).addKey(k).buildCompositeIndex()
m.makeEdgeLabel('votesFor').make()
m.commit()
getOrCreate = { id ->
def p = g.V('userId', id)
if (p.hasNext()) {
p.next()
} else {
g.addVertex([userId:id])
}
}
new File('wiki-Vote.txt').eachLine {
if (!it.startsWith("#")){
(fromVertex, toVertex) = it.split('\t').collect(getOrCreate)
fromVertex.addEdge('votesFor', toVertex)
}
}
g.commit()

Use of console.time

I'm creating an application with Google Closure Library and its Compiler. To debug values I use console.log(). Compiling this will throw the following exception JSC_UNDEFINED_VARIABLE. variable console is undeclared at .... To solve this error, I just had to use window.console.log() instead.
I also want to measure the time that a function takes. Firebug has two nice functions console.time(name) and console.timeEnd(name) to do that very easily. Unfortunately the Closure Compiler does not support these functions throwing the following warning JSC_INEXISTENT_PROPERTY. Property time never defined on Window.prototype.console at .... Unfortunately you cannot solve this warning with prepending window.
I also had a look at the library, but goog.debug.Console has not the function that I need.
Another solution I have used before was something like the following
var start = new Date();
// do something
var end = new Date();
// do some calculation to get the ms for both start and end
var startMS = ....;
var endMS = .....;
// get the difference and print it
var difference = (endMS - startMS) / 1000;
console.log('Time taken for something: ' + difference);
This is a little bit too much code, if you use it very often, and the version with the two functions would be great:
window.console.time("timeTaken");
// do something
window.console.timeEnd("timeTaken");
This prints out the MS between start and end. But as mentioned above, this doesn't work with the closure compiler. Does anyone have a solution for this, how I can use these two functions window.console.time() and window.console.timeEnd()? Or maybe another solution that goog.closure provides, but I haven't found?
You just need to added them to the externs you are using.
If you don't want to/can't use externs, you can easily reference "undeclared" objects with the string-based properties:
window['console']['log']('Hello Console!');
window['console']['time']('timeTaken');
...
But you have to be careful, because the second line might throw an error if the time property does not exist or it's not a function.

Resources