I have a FAKE script that is attempting to run MSTest.
I am getting a 'Not Defined' error on MSTest.
From what I can gather in the documentation the MSTest helper should be in FakeLib.dll and in the 'Fake' namespace. Is that wrong?
Why would I be getting this error?
#I "packages/FAKE/tools"
#r "packages/FAKE/tools/FakeLib.dll"
open Fake
... many build steps working fine
Target "UnitTest" (fun _ ->
trace "Run Unit Tests..."
!! (testDir ## "*.Tests.dll")
|> MSTest (fun p -> { p })
()
)
I had to include the open Fake.MSTest. Below is the snippet I use for unit tests.
open Fake.MSTest
Target "UnitTests" (fun _ ->
let msTestParams p =
{ p with
ResultsDir = resultsDir
WorkingDir = testOutDir
TestSettingsPath = sd ## "Local.testsettings"
ErrorLevel = ErrorLevel.Error
NoIsolation = false }
!! (testOutDir + #"\*.Tests.dll")
|> MSTest msTestParams
)
Related
Following version is calling all functions synchronously,
I'm looking to find out how to call asynchronous functions in parallel and return all results and errors to the caller.
Request
let requestAsync (url: string) : Async<Result<string, Error>> =
async {
Console.WriteLine ("Simulating request " + url)
try
do! Async.Sleep(1000)
return Ok (url + ": body...")
with :? WebException as e ->
return Error {code = 500; message = "Internal Server Error";}
}
Test
[<TestMethod>]
member this.TestrequestAsync() =
let urls = [|
"http://www.example.com/1";
"http://www.example.com/2";
"http://www.example.com/3";
"http://www.example.com/4";
"http://www.example.com/5";
"http://www.example.com/6";
"http://www.example.com/7";
"http://www.example.com/8";
"http://www.example.com/9";
"http://www.example.com/10";
|]
urls
|> Array.map (fun url -> requestAsync url |> Async.RunSynchronously) // Async.Parallel some mismatch
// Iterate results
Ideally to be able to match Ok and Error results while iterating through results
Edit based on the answer.
let result =
urls
|> Seq.map Entity.requestDetailAsync2
|> Async.Parallel
|> Async.RunSynchronously
result
|> Array.iter Console.WriteLine // match x with Ok and Error?
Attempt
result |> Array.iter (fun data -> match data with
| Ok result -> Console.WriteLine(result)
| Error error -> Console.WriteLine(error) )
Iteration using For in
for r in result do
match r with
| Ok re -> Console.WriteLine(re)
| Error error -> Console.WriteLine(error)
You can use Async.Parallel to run many async operations in parallel:
let results =
urls
|> Seq.map requestAsync // seq<Async<'T>>
|> Async.Parallel // async<T' []>
|> Async.RunSynchronously // T' []
Here's a very similar example on MSDN.
There may be an issue with your requestAsync function return type, or a missing type definition in your example. Here's what I used to verify the solution:
type RequestError = {
code : int
message : string
}
let requestAsync (url: string) =
async {
Console.WriteLine ("Simulating request " + url)
try
do! Async.Sleep(1000)
return Ok (url + ": body...")
with :? WebException as e ->
return Error {code = 500; message = "Internal Server Error";}
}
I'm trying to execute the following F# script code on my macbook pro using FSI in visual studio code and the ionide plugin.
#r "packages/Newtonsoft.Json.9.0.1/lib/net40/Newtonsoft.Json.dll"
#r "System.Net.Http"
open System
open System.Net.Http
open Newtonsoft.Json
let client = new HttpClient()
type AlbumInfo = { userId:int; id:int; title:string }
let url = "https://jsonplaceholder.typicode.com/albums/1"
async {
let! res = Async.AwaitTask <| client.GetAsync(url)
let! content = Async.AwaitTask <| res.Content.ReadAsStringAsync()
let x = JsonConvert.DeserializeObject<AlbumInfo>(content)
printfn "%s" x.title
} |> Async.Start
printfn "Please wait..."
But I don't get any output apart from Please wait.... However, when I put https://jsonplaceholder.typicode.com/albums/1 into the browser I get the expected Json response. So I know there's no problem reaching the API.
Also, when I run the same code in Visual Studio 2013 on my Windows 10 PC. The code produces the expected result. i.e. Please wait... and the title of the album.
Any ideas why it doesn't work correctly on my macbook?
In Visual Studio there is a process hosting FSI and keeping the thread (pool) for the async computation alive. In FSI on the command line or VS Code, FSI will just terminate as soon as the main thread has finished writing Please wait... (which typically is before the computation was even started on the thread pool).
If you want to observe the side effects of an async computation you have to await its result (in this example unit):
let computation = async {
printfn "Starting async"
let! res = Async.AwaitTask <| client.GetAsync(url)
let! content = Async.AwaitTask <| res.Content.ReadAsStringAsync()
let x = JsonConvert.DeserializeObject<AlbumInfo>(content)
printfn "Downloaded %s" x.title
}
async {
let! started = computation |> Async.StartChild
let! _ = Async.Sleep 1 // only here to get interleaved ouput
printfn "Please wait..."
let! res = started
printfn "Got result %A" res
} |> Async.RunSynchronously
will likely print:
Starting async
Please wait...
Downloaded quidem molestiae enim
Got result <null>
I am working on a program in which I would like to use lablgtk and lwt. I have functions fetching data on lwt threads, then I would like to display the data in a GUI using lablgtk. I am struggling with the integration of lablgtk in the lwt framework. Below is a distilled version that demonstrates my problem which is that I can get the GUI to launch, but then nothing else happens. Any help is greatly appreciated.
(* gtk_and_lwt.ml *)
let (>>=) = Lwt.bind
let locale = GtkMain.Main.init ()
let window = GWindow.window ~width:300 ~height:200 ()
let vbox = GPack.vbox ~border_width:2 ~packing:window#add ()
let my_table =
GPack.table
~rows:1
~columns:2
~row_spacings:5
~col_spacings:5
~border_width:5
~packing:vbox#pack
()
let _ =
GMisc.label
~text:"User Input"
~packing:(my_table#attach ~left:0 ~top:1 ~right:1 ~bottom:2)
()
let my_label =
GMisc.label
~text:"Fetching User Input..."
~packing:(my_table#attach ~left:1 ~top:0 ~right:2 ~bottom:1)
()
let rec get_user_input () =
Lwt_io.read_line Lwt_io.stdin
>>= fun s -> my_label#set_text s |> Lwt.return
>>= get_user_input
let main () =
(* Kill the process when the user clicks the "X" button in top left cornet*)
let _ = window#connect#destroy ~callback:GMain.Main.quit in
window#show ();
Lwt.async (get_user_input);
Lwt.return ## GMain.Main.main ()
let _ = Lwt_main.run ## main ()
I am compiling with ocamlfind ocamlc -g -package lwt,lwt.syntax,lwt.unix,lablgtk2 -linkpkg gtk_and_lwt.ml -o GtkAndLwt
I have a mono/.Net 4.5 app that compiles just fine. But whe I run it I get a Method missing Http.Request. The code in question is this
let private post url parser body =
let res = Http.Request (
url,
body = (body |> TextRequest),
silentHttpErrors = true,
headers = [
Accept HttpContentTypes.Json
ContentType HttpContentTypes.Json
]
)
let body =
match res.Body with
HttpResponseBody.Text str -> str
| _ -> failwith "Only text replies are supported"
if res.StatusCode >= 200 && res.StatusCode < 300 then
body |> parser
else
body |> errorParser
It doesn't seem to be related with the actual method because all method calls from FSharp.Data seems to fail.
I'm experiencing this both when running some standard nunit tests or when executing.
I would seem that the issue was that I had FSharp.Data.TypeProviders installed in the GAC. removing that
gacutil -u FSharp.Data.TypeProviders
solved it
I really often use:
try
try
with
finally
so I'm interesting if is possible to make new syntax operator to not write "try" two times.
let mytry foo bar foobar =
try
try
foo
with
| _ -> bar // weird part here, I want to have a match
finally foobar
mytry
<| foo
<| | :? SocketException ->
| _ -> // ok it looks funny but how to realize it?
<| foobar
the problems I see here are
non-common syntax, in mytry there is no try with finally keywords, just <| <| <| for each, but it's lesser trouble I guess
with: I don't know how can I realize this part. even how it will look if I can realize it...
The question is whether you really need try/finally. Most of the time try/finally is used for disposing resources even when exceptions occur. But you can always replace it by the use keyword.
For example:
open System.IO
let openFile(url: string) =
let fileStream = File.OpenText(url)
try
try
let readline = fileStream.ReadLine()
printfn "Readline: %s" readline
with
| :? IOException as ex ->
printfn "IOException: %A" ex
| ex -> printfn "Another exception: %A" ex
finally
fileStream.Dispose()
can be rewritten as:
let openFile(url: string) =
use fileStream = File.OpenText(url)
try
let readline = fileStream.ReadLine()
printfn "Readline: %s" readline
with
| :? IOException as ex ->
printfn "IOException: %A" ex
| ex -> printfn "Another exception: %A" ex
For the learning purpose, you can define mytry using high-order functions as follows:
let mytry foo bar foobar =
try
try
foo ()
with
| exn -> bar exn
finally foobar ()
But it doesn't look really nice on above example:
let myOpenFile(url: string) =
let fileStream = File.OpenText(url)
mytry (fun () -> let readline = fileStream.ReadLine()
printfn "Readline: %s" readline)
(fun ex -> match ex with
| :? IOException ->
printfn "IOException: %A" ex
| _ -> printfn "Another exception: %A" ex)
(fun () -> fileStream.Dispose())
You can write a higher-order function that takes the three parts as separate function. The body of the try would be a function unit -> 'R where 'R is the result. The exception handler will need to handle only some exceptions, so you can return option to say whether you handled the result or if you want the exception to be rethrown. The type of handler will be exn -> 'R option. The finalizer is then simply a function unit -> unit.
The usage is not as elegant as using built-in language feature, but it does the trick:
tryWithFinally
(fun () ->
1/0 ) // The nested body
(function
| :? DivideByZeroException -> Some -1 // Handle division by zero
| _ -> None ) // Rethrow any other exceptions
(fun () ->
printfn "done" )
The implementation is quite easy once you know the structure, but for completeness, here it is:
let tryWithFinally f handler finalizer =
try
try f()
with e ->
match handler e with
| Some r -> r
| None -> reraise()
finally
finalizer()
Anyway, I agree with #pad that in most of the cases, you should be fine with just use and try .. with.