I am using FsUnit 2.1 (with NUnit 3.2) to write tests for an F# project. Here is a simple module:
namespace Library1
module LibraryFunctions =
let Execute f1 = f1()
let Id x = x
And here are my tests:
namespace Tests
open FsUnit
open NUnit.Framework
open Library1
[<TestFixture>]
type Tests() =
[<Test>]
// Passes
member x.``LibraryFunctions.Id should return the value``() =
LibraryFunctions.Id 42 |> should equal 42
[<Test>]
// Fails
member x.``LibraryFunctions.Execute should return the result of the function``() =
let f() = 42
LibraryFunctions.Execute f |> should equal 42
The second test fails (in NCrunch and ReSharper) with the message:
System.MissingMethodException : Method not found: '!!0 Library1.LibraryFunctions.Execute(Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,!!0>)'.
If I put the module under test in the same code file as the tests (rather than in a separate VS project) the test passes. My suspicion is that this is due to some issue with NUnit and F#/C# interop. If so, how can it be resolved?
This is a known issue with FsUnit and other projects (see here and here).
As a workaround, you can add this to your app.config file:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
NB: you'll need update4.3.0.0 to whatever version of FSharp.Core your FsUnit assembly is using, as and when it is updated.
Related
I'm having difficulties using RBush from F#. The library requires me to define a class that implements the following interface.
public interface ISpatialData
{
ref readonly Envelope Envelope { get; }
}
Below is the code of a console application that compiles fine, where Point class implements the ISpatialData interface.
open RBush
type Point(minX, minY, maxX, maxY) =
let mutable envelope = Envelope(minX, minY, maxX, maxY)
interface ISpatialData with
member __.Envelope = &envelope
[<EntryPoint>]
let main _ =
let tree = RBush<Point>()
0
However, when the application is run it throws: System.MissingMethodException: 'Method not found: 'RBush.Envelope ByRef RBush.ISpatialData.get_Envelope()'.'
If I send the Point class definition to F# Interactive I get the following error: error FS0193: internal error: Signature of the body and declaration in a method implementation do not match. Type: 'Point'. Assembly: 'FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Any ideas what I'm doing wrong?
This usually indication of you using different FSharp.Core than used for the library. Modify app.config to have following:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=_Your .Net Version_" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-_Your FSharp.Core Version_" newVersion="_Your FSharp.Core Version_" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Hi I am trying to run FsCheck.Xunit tests with xunit.runner.console and getting the following exception:
Kata.TennisProperties.Given advantaged player when advantaged player wins score is correct [FAIL]
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
---- System.Exception : The type Kata.Tennis+Player is not handled automatically by FsCheck. Consider using another type or writing and registering a generator for it.
Stack Trace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
I am trying to follow Mark Seemann's talk. My setup is as follows:
I have a single library type project whith two files. One with the code to be tested and one with the test code. The project compile just fine. I am not using the VS IDE but just VSCode text editor with Ionide plugin for F#.
I have tried with various setups with and without FSharp.Core nuget installs, with and without version specification of FSharp.Core.
Any idea where to look further? I am running out of ideas and getting frustrated. I've already spent two days on this. :)
Fixed this by adding the app.config file bellow.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<Paket>True</Paket>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I did this before but using VSCode + Ionide didn't got the config file added to the project. So, very important, don't forget to add the app.config file to the project also. It is not enough to just create the file in project folder.
I'm trying to integrate stimulsoft designer in my web application (MVC4, Razor 2 and Entity Framework 4) but I have encountred some problems.
I have integrated the dlls and the assemblies, but I have this error :
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Source Error: #Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions() {
The problem was resolved by making following changes in the Web.Config file:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
I created a websharper sitelet project from Visual Studio 2012, which I called SiteletTest.
I compiled this project.
Then I copied SiteletTest/Web to inetpub/wwwroot.
Then I go to localhost/SiteletTest, localhost/SiteletTest/Home and localhost/SiteletTest/home but in each case I get http 404.
If I go to localhost/Main.html then I get a page, so going to this directory seems to work, but websharper doesn't appear to be working.
My web.config is below, and I have no idea what else to do. I already set the application pool to use .net 4:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<authentication mode="Forms" />
<pages>
<controls>
<add tagPrefix="WebSharper" namespace="IntelliFactory.WebSharper.Web" assembly="IntelliFactory.WebSharper.Web" />
<add tagPrefix="ws" namespace="Website" assembly="Website" />
</controls>
</pages>
<httpModules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
<assemblyBinding appliesTo="v4.0.30319" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I am not going to be paying for a license until I get an idea if this may work for my needs, so, how do I get this to work?
I don't want to copy the sitelet code, but here are some fragments:
type Action =
| Home
| Contact
| Protected
| Login of option<Action>
| Logout
| Echo of string
and another fragment:
module Pages =
/// The home page.
let HomePage : Content<Action> =
Skin.WithTemplate "Home" <| fun ctx ->
[
H1 [Text "Welcome to our site!"]
"Let us know how we can contact you" => ctx.Link Action.Contact
]
I'm pretty sure you are missing 1 of three things:
1- Your sitelet/router isn't defined... something like this:
type Site() =
interface IWebsite<Action> with
member x.Sitelet =
Sitelet.Infer
<| function
| Home -> Pages.HomePage
...
member x.Actions = []
This maps each of the action cases to the correct page. There are many ways to define it but the above Sitelet.Infer will simply map the route by name.
2- You did not specify a Website assembly attribute... something like this:
[<assembly : Website(typeof<Site>)>]
do ()
I think this tells ASP.NET to load the above Sitelet as your site.
3- A third option is to automatically load a client-side JavaScript control from a Default.aspx page in the C# Web Project. If you use the Web Application (ASP.NET) template, you will see an example of that... but with that I do not think you can control the URL Path in a REST-full manner.
I'm getting the following warning when I right click on T4MVC.tt and select "run custom tool" (i.e. rebuild by T4MVC.cs file).
Warning 1
Compiling transformation: Assuming assembly reference 'EnvDTE, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
matches 'EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a',
you may need to supply runtime policy
C:\Development\EHealth-Trunk\src\EHealth.Web\T4MVC.tt 1 1
It's no big deal really, I just don't like to have (unnecessary) warnings in my code-base...
I haven't quite figured out what the problem is, but I did isolate it to a small repro where this happens:
<## template language="C#" #>
<## assembly name="EnvDTE" #>
<## assembly name="VSLangProj" #>
<#+
void Test(EnvDTE.Project Project) {
var vsProject = (VSLangProj.VSProject)Project.Object;
var refs = vsProject.References;
}
#>
Which gets the following warning during processing:
Compiling transformation: Assuming assembly reference 'EnvDTE, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' matches 'EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a', you may need to supply runtime policy
The only EnvDTE in my GAC is 8.0.0.0. It seems that the problem relates to the fact that VSLangProj 7.0.3300.0 (the only one I have) has a reference to EnvDTE 7.0.3300.0, which doesn’t exist.
Clearly, this is not an 'answer' quite yet, but it's the beginning of the investigation :)
Change:
<## assembly name="EnvDTE" #>
To:
<## assembly name="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" #>
in T4MVC.tt and it will remove the compiler warning :)
David - I'm going to submit a pull request with the fix to MvcContrib soon - just let me know that you are happy with that solution before I do it :)
Add app.config and paste this code below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" appliesTo="v2.0.50318">
<dependentAssembly>
<assemblyIdentity name="EnvDTE" publicKeyToken=
"b03f5f7f11d50a3a"/>
<bindingRedirect oldVersion="7.0.3300.0"
newVersion="8.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>