I'm new to using FakeItEasy and rather stuck at my first attempt. The interface i want to fake has a method like this:
byte[] ReadFileChunk(string path,int offset,int count,out long size);
I would like to see how the arguments are passed on, so I'm using ReturnsLazily. Here is my attempt:
long resSize;
A.CallTo(() => dataAttributesController
.ReadFileChunk(A<string>.Ignored, A<int>.Ignored, A<int>.Ignored, out resSize))
.ReturnsLazily((string path, int offset, int count) =>
{
return Encoding.UTF8.GetBytes("You requested: " + path + "(" + offset + "," + count + ")");
})
.AssignsOutAndRefParameters(123);
This compiles, but when ran it generates this exception:
The faked method has the signature (System.String, System.Int32, System.Int32, System.Int64&), but returns lazily was used with (System.String, System.Int32, System.Int32).
Which is correct, but i can't figure out how to add the out parameter. If I change the ReturnLazily part to this:
.ReturnsLazily((string path, int offset, int count, out long size) =>
{
size = 0;
return Encoding.UTF8.GetBytes("You requested: " + path + "(" + offset + "," + count + ")");
})
it will not compile, and I don't understand the errors:
error CS1593: Delegate 'System.Func<FakeItEasy.Core.IFakeObjectCall,byte[]>' does not take 4 arguments
error CS1661: Cannot convert lambda expression to delegate type 'System.Func<string,int,int,long,byte[]>' because the parameter types do not match the delegate parameter types
error CS1677: Parameter 4 should not be declared with the 'out' keyword
For a novice like me, this reads like it doesn't like 4 parameters nor understands what to do with 'out'. Can someone please explain me how I should be reading these errors? A working example would be very welcome as well :-)
Thanks a lot!
--- EDIT ---
This seems to work:
A.CallTo(() => dataAttributesController
.ReadFileChunk(A<string>.Ignored, A<int>.Ignored, A<int>.Ignored, out resSize))
.ReturnsLazily(x =>
Encoding.UTF8.GetBytes("You requested: " + x.Arguments.Get<string>(0) + "(" + x.Arguments.Get<int>(1) + "," + x.Arguments.Get<int>(2) + ")"))
.AssignsOutAndRefParameters((long)123);
A bit less readable then I was hoping for, is this anywhere near the intended use of ReturnsLazily?
Is that interface under your control?
byte[] ReadFileChunk(string path, int offset, int count, out long size);
if so: Isn't out long size just the same as the size of the returning byte[]?
In that case I would just remove the size parameter from the interface method and use the "nice-to-read" ReturnsLazily method as you intended first.
Update: the issue I mention below was fixed in FakeItEasy release 1.15, so update to the latest version and you shouldn't have to worry about the out/ref specifiers on the methods when using ReturnsLazily.
Sorry for the delay. I'm glad you found a solution that at least functions for you.
I agree that the syntax you landed on isn't the most readable, but it does appear to be the correct one. The "convenience" versions of ReturnsLazily won't work with out/ref parameters because the lambda can't take the out/ref modifiers.
It doesn't help you today, but I've created FakeItEasy issue 168 to deal with the problem. If you have additional opinions, please drop by and comment or something.
Related
In the docs says:
The setValueAtTime() method of the AudioParam interface schedules an instant change to the AudioParam value at a precise time, as measured against AudioContext.currentTime. The new value is given in the value parameter.
From what one can think it makes an instant change but when a run this code
...
biquadNode.gain.setValueAtTime(12, this._AudioContext.currentTime);
console.log("biquadNode.gain " + biquadNode.gain.value);
console.log("biquadNode.frequency " + biquadNode.frequency.value);
setTimeout(() => {
console.log("biquadNode.gain " + biquadNode.gain.value);
console.log("biquadNode.frequency " + biquadNode.frequency.value);
}, 100);
...
It outputs:
0
12
I am not sure why...
It's instant, right, yet asynchronous (and is assumed to be a non-blocking op), as it's executed in a separate thread - note the word schedules in the description. That's why you won't see the change immediately.
Note that another method of updating value, via direct assignment to the corresponding property...
biquadNode.gain.value = 12;
... isn't synchronous either - and is basically equivalent to setValueAtTime(newValue, currentTime), as explained in this issue.
I have a function in scala which has no return-value (so unit). This function can sometimes fail (if the user provided parameters are not valid). If I were on java, I would simply throw an exception. But on scala (although the same thing is possible), it is suggested to not use exceptions.
I perfectly know how to use Option or Try, but they all only make sense if you have something valid to return.
For example, think of a (imaginary) addPrintJob(printJob: printJob): Unit command which adds a print job to a printer. The job definition could now be invalid and the user should be notified of this.
I see the following two alternatives:
Use exceptions anyway
Return something from the method (like a "print job identifier") and then return a Option/Either/Try of that type. But this means adding a return value just for the sake of error handling.
What are the best practices here?
You are too deep into FP :-)
You want to know whether the method is successful or not - return a Boolean!
According to this Throwing exceptions in Scala, what is the "official rule" Throwing exceptions in scala is not advised as because it breaks the control flow. In my opinion you should throw an exception in scala only when something significant has gone wrong and normal flow should not be continued.
For all other cases it generally better to return the status/result of the operation that was performed. scala Option and Either serve this purpose. imho A function which does not return any value is a bad practice.
For the given example of the addPrintJob I would return an job identifier (as suggested by #marstran in comments), if this is not possible the status of addPrintJob.
The problem is that usually when you have to model things for a specific method it is not about having success or failure ( true or false ) or ( 0 or 1 - Unit exit codes wise ) or ( 0 or 1 - true or false interpolation wise ) , but about returning status info and a msg , thus the most simplest technique I use ( whenever code review naysayers/dickheads/besserwissers are not around ) is that
val msg = "unknown error has occurred during ..."
val ret = 1 // defined in the beginning of the method, means "unknown error"
.... // action
ret = 0 // when you finally succeeded to implement FULLY what THIS method was supposed to to
msg = "" // you could say something like ok , but usually end-users are not interested in your ok msgs , they want the stuff to work ...
at the end always return a tuple
return ( ret , msg )
or if you have a data as well ( lets say a spark data frame )
return ( ret , msg , Some(df))
Using return is more obvious, although not required ( for the purists ) ...
Now because ret is just a stupid int, you could quickly turn more complex status codes into more complex Enums , objects or whatnot , but the point is that you should not introduce more complexity than it is needed into your code in the beginning , let it grow organically ...
and of course the caller would call like
( ret , msg , mayBeDf ) = myFancyFunc(someparam, etc)
Thus exceptions would mean truly error situations and you will avoid messy try catch jungles ...
I know this answer WILL GET down-voted , because well there are too much guys from universities with however bright resumes writing whatever brilliant algos and stuff ending-up into the spagetti code we all are sick of and not something as simple as possible but not simpler and of course something that WORKS.
BUT, if you need only ok/nok control flow and chaining, here is bit more elaborated ok,nok example, which does really throw exception, which of course you would have to trap on an upper level , which works for spark:
/**
* a not so fancy way of failing asap, on first failing link in the control chain
* #return true if valid, false if not
*/
def isValid(): Boolean = {
val lst = List(
isValidForEmptyDF() _,
isValidForFoo() _,
isValidForBar() _
)
!lst.exists(!_()) // and fail asap ...
}
def isValidForEmptyDF()(): Boolean = {
val specsAreMatched: Boolean = true
try {
if (df.rdd.isEmpty) {
msg = "the file: " + uri + " is empty"
!specsAreMatched
} else {
specsAreMatched
}
} catch {
case jle: java.lang.UnsupportedOperationException => {
msg = msg + jle.getMessage
return false
}
case e: Exception => {
msg = msg + e.getMessage()
return false
}
}
}
Disclaimer: my colleague helped me with the fancy functions syntax ...
I am trying to develop a deeper understanding of map/reduce in MongoDB.
I figure the best way to accomplish this is to look at emit's actual implementation. Where can I find it?
Even better would just be a simple implementation of emit(). In the MongoDB documentation, they show a way to troubleshoot emit() by writing your own, but the basic implementation they give is really too basic.
I'd like to understand how the grouping is taking place.
I think the definition you are looking for is located here:
https://github.com/mongodb/mongo/blob/master/src/mongo/db/commands/mr.cpp#L886
There is quite a lot of context needed though to fully understand what is going on. I confess, I do not.
1.Mongo's required JS version is no longer in O.Powell's url, which is dead. I cannot find it.
2.The below code seems to be the snippet of most interest. This cpp function, switchMode, computes the emit function to use. It is currently at;
https://github.com/mongodb/mongo/blob/master/src/mongo/db/commands/mr.cpp#L815
3.I was trying to see if emit has a default to include the _id key, which seems to occur via _mrMap, not shown here. Elsewhere it is initialized to {}, the empty map.
void State::switchMode(bool jsMode) {
_jsMode = jsMode;
if (jsMode) {
// emit function that stays in JS
_scope->setFunction("emit",
"function(key, value) {"
" if (typeof(key) === 'object') {"
" _bailFromJS(key, value);"
" return;"
" }"
" ++_emitCt;"
" var map = _mrMap;"
" var list = map[key];"
" if (!list) {"
" ++_keyCt;"
" list = [];"
" map[key] = list;"
" }"
" else"
" ++_dupCt;"
" list.push(value);"
"}");
_scope->injectNative("_bailFromJS", _bailFromJS, this);
}
else {
// emit now populates C++ map
_scope->injectNative( "emit" , fast_emit, this );
}
}
Consider the below code snippet
string src = "ibm,tcs";
string dest = src.Split(',').Select(i => i + "();,").ToArray().Aggregate((s, i) => s + i);
dest = dest.Substring(0, dest.Length - 1);
What I am doing is that, the Source string(src here) will have the string list in comma separated way.
The final output will be: ibm();,tcs();
As we can make out that, my program is doing so.
But I am taking the help of dest.Substring(0, dest.Length - 1); for eliminating the last "," that I am building in the Select Extension method.
I don't like this approach of mine.
Is there any other beautiful / elegant way of doing so? I am sure that someone will definitely approach in a better way :)
Also I will be happy if I get a solution using Lambda & Extension Method.
I am using C# 3.0 and dot net framework 3.5
Thanks
Just use string.Join instead of Aggregate, and don't include the comma in the Select clause:
string dest = string.Join(",", src.Split(',')
.Select(i => i + "();")
.ToArray());
In .NET 4 you wouldn't even need the ToArray() call (as extra overloads have been added to string.Join).
Or, as a completely alternative approach:
string dest = src.Replace(",", "();,") + "();";
string dest = string.Join(",", src.Split(',').Select(i => i + "();").ToArray());
or
string dest = string.Join(",", Array.ConvertAll(src.Split(','), s => s + "();"));
I've coded a parser based on Scala parser combinators:
class SxmlParser extends RegexParsers with ImplicitConversions with PackratParsers {
[...]
lazy val document: PackratParser[AstNodeDocument] =
((procinst | element | comment | cdata | whitespace | text)*) ^^ {
AstNodeDocument(_)
}
[...]
}
object SxmlParser {
def parse(text: String): AstNodeDocument = {
var ast = AstNodeDocument()
val parser = new SxmlParser()
val result = parser.parseAll(parser.document, new CharArrayReader(text.toArray))
result match {
case parser.Success(x, _) => ast = x
case parser.NoSuccess(err, next) => {
tool.die("failed to parse SXML input " +
"(line " + next.pos.line + ", column " + next.pos.column + "):\n" +
err + "\n" +
next.pos.longString)
}
}
ast
}
}
Usually the resulting parsing error messages are rather nice. But sometimes it becomes just
sxml: ERROR: failed to parse SXML input (line 32, column 1):
`"' expected but `' found
^
This happens if a quote characters is not closed and the parser reaches the EOT. What I would like to see here is (1) what production the parser was in when it expected the '"' (I've multiple ones) and (2) where in the input this production started parsing (which is an indicator where the opening quote is in the input). Does anybody know how I can improve the error messages and include more information about the actual internal parsing state when the error happens (perhaps something like a production rule stacktrace or whatever can be given reasonably here to better identify the error location). BTW, the above "line 32, column 1" is actually the EOT position and hence of no use here, of course.
I don't know yet how to deal with (1), but I was also looking for (2) when I found this webpage:
https://wiki.scala-lang.org/plugins/viewsource/viewpagesrc.action?pageId=917624
I'm just copying the information:
A useful enhancement is to record the input position (line number and column number) of the significant tokens. To do this, you must do three things:
Make each output type extend scala.util.parsing.input.Positional
invoke the Parsers.positioned() combinator
Use a text source that records line and column positions
and
Finally, ensure that the source tracks positions. For streams, you can simply use scala.util.parsing.input.StreamReader; for Strings, use scala.util.parsing.input.CharArrayReader.
I'm currently playing with it so I'll try to add a simple example later
In such cases you may use err, failure and ~! with production rules designed specifically to match the error.