Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can Hedgehog.Xunit generate functions? #9

Open
moodmosaic opened this issue Aug 16, 2022 · 2 comments
Open

Can Hedgehog.Xunit generate functions? #9

moodmosaic opened this issue Aug 16, 2022 · 2 comments

Comments

@moodmosaic
Copy link
Member

@dharmaturtle, with @cmeeren we've discussed function generation in the past. Could that work with Hedgehog.Xunit?

using Hedgehog;
using Hedgehog.Xunit;

using System;
using System.Collections.Generic;
using System.Linq;

using Xunit;
using Xunit.Abstractions;

public class Properties
{
    public static Func<Guid, int> Combine(
        Func<Guid, int> f,
        Func<Guid, int> g)
    {
        return x => f(x) + g(x);
    }

    [Property]
    public void CombineIsAssociative(
        Func<Guid, int> f,
        Func<Guid, int> g,
        Func<Guid, int> h,
        Guid guid)
    {
        Assert.Equal(
            Combine(Combine(f, g), h)(guid),
            Combine(f, Combine(g, h))(guid));
    }
}

Output:

System.NotSupportedException:
  Unable to auto-generate System.IntPtr. You can use
  'GenX.defaults |> AutoGenConfig.addGenerator myGen |> GenX.autoWith'
  to generate types not inherently supported by GenX.auto.
@dharmaturtle
Copy link
Member

dharmaturtle commented Aug 17, 2022

It should yeah, as long as you register the function generator with the correct types. This (trivially) passes on my machine:

using Hedgehog;
using Hedgehog.Xunit;

public class AutoGenConfigContainer
{
  public static AutoGenConfig X()
  {
    var fgen = Gen.constant<Func<Guid, int>>((_) => 1);
    return AutoGenConfigModule.addGenerator(fgen).Invoke(GenX.defaults);
  }
}

public class Properties
{
  public static Func<Guid, int> Combine(
      Func<Guid, int> f,
      Func<Guid, int> g)
  {
    return x => f(x) + g(x);
  }

  [Property(typeof(AutoGenConfigContainer))]
  public void CombineIsAssociative(
      Func<Guid, int> f,
      Func<Guid, int> g,
      Func<Guid, int> h,
      Guid guid)
  {
    Assert.Equal(
        Combine(Combine(f, g), h)(guid),
        Combine(f, Combine(g, h))(guid));
  }
}

My C# is very rusty, and I've little experience with its LINQ syntax, so I hope it's enough to get you unstuck. I think the ideal solution would be to use GenX.withMapTo like

var ingen = Gen.list(Hedgehog.Range.linear(0, 100), Gen.guid);
var outgen = Gen.int16(Hedgehog.Range.linear<short>(0,100));
var tuplegen = GenX.withMapTo(outgen, ingen);

but then I realized I didn't know how to get the value out of my monad in C# - and I hope you know how to :D

@moodmosaic
Copy link
Member Author

Thank you 👍 I'll try it and let you know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants