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

Add Faqt link to docs #2299

Closed
cmeeren opened this issue Sep 12, 2023 · 12 comments · Fixed by #2309
Closed

Add Faqt link to docs #2299

cmeeren opened this issue Sep 12, 2023 · 12 comments · Fixed by #2309

Comments

@cmeeren
Copy link

cmeeren commented Sep 12, 2023

Background and motivation

Continuing from #2225 (comment) and subsequent comments.

Since F# support is deemed out of scope, I am wondering if you are open to linking to Faqt. I imagine this could be done simply by adding a new page to the menu called "F# usage", around here:

image

On that page, we could have something like this:

F# usage

We encourage F# developers to try out Faqt, an assertion library inspired by FluentAssertions and made specifically for F#.

FluentAssertions is made with C# in mind. While it can be used from F#, the syntax will be more verbose due to how F# overload resolution works. Improving F# usage issues is deemed out of scope for FluentAssertions.

If you want me to submit a PR, please let me know approximately where I need to change things, and I'll jump on it.

Alternative Concerns

No response

Are you willing help with a pull-request?

Yes, please assign this issue to me.

@dennisdoomen
Copy link
Member

@jnyrup I'm fine with this, but what about you?

@jnyrup
Copy link
Member

jnyrup commented Sep 15, 2023

Since F# support is #2225 (comment)

As long as it isn't formulated as we don't have any support at all for F# (because that is not true) I'm absolute fine with adding docs.

I imagine that page could evolve into something like:

  • Here's how you best use Fluent Assertions with F# to workaround language differences between C# and F#
    • This is where Dennis and I as C# developers need help from the community
  • If you're looking for a testing library designed for especially for F# from the bottom have a look at Faqt.

@cmeeren
Copy link
Author

cmeeren commented Sep 15, 2023

As long as it isn't formulated as we don't have any support at all for F# (because that is not true) I'm absolute fine with adding docs.

How do you feel about the suggested wording in the first post above? (See the quoted section.) I think it satisfies your requirement.

@jnyrup
Copy link
Member

jnyrup commented Sep 15, 2023

I think the wording is too harsh on FluentAssertions.
We don't deem all F# improvements out of scope for FA - e.g. I just recently merged #2254 to test our caller identification works on F# (My first F# program ever).

The linked issue we deemed out of scope because the suggestion of doubling the API surface is only necessary for F#.
I still suggest someone creating a polyfill library FluentAssertions.FSharp to mitigate some of those annoyances that exists as an F# programmer using FA.

So I think the wording should focus more on where using FA becomes clunky for F# users and where Faqt improves on that.

@cmeeren
Copy link
Author

cmeeren commented Sep 15, 2023

Sure, I'm happy to accommodate your input! Below is a revised suggestion that removes the general "out of scope" message (it limits it to the because parameter issue) and goes into more detail about the limitations. Please let me know if you would like me to make further adjustments to it.


F# usage

We encourage F# developers to try out Faqt, an assertion library inspired by FluentAssertions and made specifically for F#.

FluentAssertions is made with C# in mind. While it can be used from F#, the experience will not be as intended. In particular:

  • To aid F#'s overload resolution, you often have to cast subject values. This does not work in all cases and will only give you a subset of assertions. For example:

    let x = [1; 2]
    x.Should().Contain(1, "") // Overload resolution error for "Should"
    (x :> seq<_>).Should().Contain(1, "") // OK, but only gives access to GenericCollectionAssertions<_>

    The need to cast will break your fluent chains, defeating some of the purpose of FluentAssertions.

  • Sometimes not even casting will solve the issue, and you will have to forgo Should entirely and instead directly construct the correct assertion type. For example:

    let x = dict ["A", 1; "B", 2]
    
    // All of these give overload resolution error for "Should"
    x.Should().ContainKey(1, "")
    (x :> IDictionary<_,_>).Should().ContainKey(1, "") 
    (x :> seq<KeyValuePair<_,_>>).Should().Contain(KeyValuePair("A", 1), "")
    
    // You have to construct the desired assertion directly
    GenericDictionaryAssertions<_, _, _>(x).ContainKey("A", "")
    GenericCollectionAssertions<_, _, _>(x).Contain(KeyValuePair("A", 1), "")

    As with casting, the need to construct the assertion directly will break your fluent chains, defeating some of the purpose of FluentAssertions.

  • As can be seen above, the because parameter cannot be omitted when used from
    F# (#2225). Improving this is deemed out of scope since it would double the API surface of FluentAssertions.

  • Several assertions (specifically, those that accept an Action<_>) require an explicit ignore when used from F# (#2226).

@jnyrup
Copy link
Member

jnyrup commented Sep 16, 2023

Much better ❤️
@ursenzler Since you're probably our most active F# user, can I ask you to verify the technical side of the bullet points above?

@ursenzler
Copy link
Contributor

@jnyrup I only took a quick look. I think that everything is technically correct.

@cmeeren As a side note, and please feel free to ignore it completely: fluent chains with methods in F# are a hard sell. Chains in F# are typically done via piping into functions.

@cmeeren
Copy link
Author

cmeeren commented Sep 16, 2023

@cmeeren As a side note, and please feel free to ignore it completely: fluent chains with methods in F# are a hard sell. Chains in F# are typically done via piping into functions.

I have been working with F# full-time for more than five years now and consider myself an experienced and fairly advanced F# programmer, and I respectfully and completely disagree. Fluent syntax is fantastic, also in F#, at least for DLSs like this. The discoverability is great since you can just type a dot to discover methods; the ability to overload methods is a nice convenience that can reduce verbosity; and it's just as concise as piping (in fact more so, since you don't have to prefix everything with a module name, which is often done when piping). I made Faqt precisely because no other assertion framework (when used from F#) came close to the same convenience, discoverability, readability, and extensibility. I have also used fluent syntax in other libraries/frameworks I have created, such as Facil and Felicity, and none of the comments/issues posted to these repos have voiced any dissatisfaction with the basic fluent syntax.

@cmeeren
Copy link
Author

cmeeren commented Sep 16, 2023

@jnyrup As I understand it, my proposed text can be used. If you let me know which files to change/create and where, I can make a PR. 🙂

@jnyrup
Copy link
Member

jnyrup commented Sep 16, 2023

It is at least close enough that any last details might as well be discussed in a PR.

The individual pages are located in https://github.com/fluentassertions/fluentassertions/tree/develop/docs/_pages
The menu bar is located in https://github.com/fluentassertions/fluentassertions/blob/develop/docs/_data/navigation.yml

@cmeeren
Copy link
Author

cmeeren commented Sep 16, 2023

Great, I'll try to look at it on Monday!

@ursenzler
Copy link
Contributor

@cmeeren then your experience is different from mine, which is totally fine :-)
We'll consider Faqt for our tests that contain a mix of C# and F# data structures, for which Unqote (our favourite tool) doesn't work. At the moment, we use FluentAssertions directly, which is, as you know, not so fun. Happy coding!

This was referenced Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants