F# test if the result is Some(any) - unit-testing

I need to check whether my validation function returns something when fails or none. If it returns Some<string>, there is a validation error, otherwise it's valid and the function returns None.
This is my attempt , but it's not refactoring safe:
[<Property(Arbitrary=[| typeof<Strings.WithLenFrom1To100> |])>]
let ``lengthValidator should return some error when the string's length is longer than expected``(str:string)=
let maxValidLen = str.Length-1
let actual = lengthValidator maxValidLen str
let expected = Some(sprintf "Maximum string length is %i but %s contains %i characters" maxValidLen str str.Length)
//How can I say **let expected = Some(anything) **instead
test <#actual = expected#>

test <# actual.IsSome #>

Related

Adding a nilable variable to a non-nilable array

I have a string array named current_todos and am trying to add a variable of type (String | Nil) named new_task by doing the following:
current_todos << new_task if typeof(new_task) == String
I get the error Error: no overload matches 'Array(String)#<<' with type (String | Nil).
How can I add a nilable string to current_todos after doing a type check?
Edit: here is the full code:
require "option_parser"
current_todos = [
"Laundry",
"Walk dog",
"Sing in shower"
]
new_task = nil
OptionParser.parse do |parser|
parser.banner = "Welcome to my todo app!"
parser.on "-a TASK", "--add TASK", "Type a new task" do |task|
new_task = task
end
parser.on "-h", "--help" do
puts parser
exit
end
end
current_todos << new_task if typeof(new_task) == String
current_todos.each do |todo|
puts todo
end
If new_task is of type String|Nil, you can test if it is non-nil. Then the compiler will know that it is a string. That here should work:
current_todos << new_task if new_task
Another way that the compiler will understand, which is closer to your original code, is to use is_a?:
current_todos << new_task if new_task.is_a?(String)
typeof(var) gives the compile time type, not the type at runtime. For example:
def check_type(var : String?)
puts typeof(var)
puts var.class
puts var.is_a? String
puts var.is_a? Nil
puts var.nil?
end
check_type(gets)
If you give input, it will print:
(String | Nil)
String
true
false
false
If you don't give input (gets returns nil) then it will print:
(String | Nil)
Nil
false
true
true
Looks like the reason something like current_todos << new_task if new_task.is_a?(String) doesn't work is because the new assignment of new_task happens within the .on function of the parser. Since the compiler doesn't know when/if this is called as it is inside a closure, it resorts to nil.
To force it to work I would need to use .not_nil!

Casting regex match to String

I created a simple code in Scala that checks whether an input is correctly formatted as HH:mm. I expect the code to result in an Array of valid strings. However, what I'm getting as a result is of type Any = Array(), which is problematic as when I try to print that result I get something like that:
[Ljava.lang.Object;#32a59591.
I guess it's a simple problem but being a Scala newbie I didn't manage to solve it even after a good few hours of googling and trial & error.
val scheduleHours = if (inputScheduleHours == "") {
dbutils.notebook.exit(s"ERROR: Missing param value for schedule hours.")
}
else {
val timePattern = """^((?:[0-30]?[0-9]|2[0-3]):[0-5][0-9])$""".r
val inputScheduleHoursParsed = inputScheduleHours.split(";").map(_.trim)
for (e <- inputScheduleHoursParsed) yield e match {
case timePattern(e) => e.toString
case _ => dbutils.notebook.exit(s"ERROR: Wrong param value for schedule hours: '${inputScheduleHours}'")
}
}
The problem is that some branches return the result you want and others return dbutils.notebook.exit which (I think) returns Unit. Scala must pick a type for the result that is compatible with both Unit and Array[String], and Any is the only one that fits.
One solution is to add a compatible value after the calls to dbutils.notebook.exit, e.g.
val scheduleHours = if (inputScheduleHours == "") {
dbutils.notebook.exit(s"ERROR: Missing param value for schedule hours.")
Array.empty[String]
}
Then all the branches return Array[String] so that will be the type of the result.

Finding a string in a phrase

I am using regexpi to find a string in a phrase. But I also encountered with something different which I never intended.
Let's say the words I need to find are anandalak and nandaki.
str1 = {'anandalak'};
str2 = {'nanda'};
button = {'nanda'};
Both of the following return me logical 1:
~cellfun('isempty',regexpi(str1,button))
~cellfun('isempty',regexpi(str2,button))
How can I avoid this? I need logical 0 in first case and logical 1 in the second.
You probably need to use the word-boundaries(\<\>) in order to get the match which you require.
You may try:
str1 = {'anandalak'}
str2 = {'nanda'}
button = {'\<nanda\>'} % Notice this
~cellfun(#isempty,regexpi(str1,button)) % Returns ans = 0 No match
~cellfun(#isempty,regexpi(str2,button)) % Return ans = 1 Exact match
You can find the sample run result of the above implementation in here.

Swift substring initialization

Currently I am trying to mess with this in playground before I implement some version of this into my actual code. I am trying to take a string and print out 4 characters. The code that is shown below, I am planning on using in a loop and increment the starting and ending position by 4 which is why there are variables currently at the starting and ending points. Before I can even get there however, I am getting an error:
error: cannot invoke initializer for type 'Range' with an argument list of type '(start: String.CharacterView.Index, end: String.CharacterView.Index)'
var str_start = 0
var str_end = 4
let sub_str = initial_str.substring(Range<String.Index>(start: initial_str.startIndex.advancedBy(str_start), end: initial_str.endIndex.advancedBy(str_end)))
I've already looked at these sources but to no avail:
Creating Range<String.Index> from constant Ints
Cannot invoke initializer for type 'Range<String.Index>' with an argument list of type '(start: String.Index, end: String.Index)'
Any assistance is greatly appreciated, and I apologize if it is a simple fix.
Here's one way to do it:
let initialString = "foo bar"
let newStartIndex = initialString.index(initialString.startIndex, offsetBy: 1)
let newEndIndex = initialString.index(initialString.endIndex, offsetBy: -1)
let substring = initialString[newStartIndex..<newEndIndex]
// this also works, but it needs `import Foundation`:
// let substring = initialString.substring(with: newStartIndex..<newEndIndex)
print(substring)
Output:
oo ba

Non-empty iterator over regex groups becomes empty array

I have this strange situation - when I print regex groups to a console, they show up. When I convert this iterator to array - it's empty. Following code doesnt print anything:
val str = "buy--751-rates.data"
val expr = "--(.+)-rates.data".r
val target = Array[String]()
expr.findAllIn(str).matchData map(m => m group 1) copyToArray(target, 0, 4)
target foreach { println }
But this snippet works:
val str = "buy--751-rates.data"
val expr = "--(.+)-rates.data".r
println("Scala matches:")
expr.findAllIn(str).matchData foreach {
m => println(m group 1)
}
I guess I missed something simple
You didn't get anything because you were copying to a zero length array. You don't actually need to do that as there is a toArray method on the iterator that converts it to and array and from that you can get the head value if you want. For example:
(expr.findAllIn(str).matchData).map(m => m group 1).toArray.head