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 regression tests for qualified type #201

Merged
merged 2 commits into from
Dec 3, 2021

Conversation

bobot
Copy link
Contributor

@bobot bobot commented Dec 1, 2021

Qualified type are currently concatenated into a unique identifier, so it becomes a constructor:

module Q = struct
   type t = int
    [@@deriving qcheck]
end

type t = Q.t
 [@@deriving qcheck]
dune runtest
File "test/ppx_deriving_qcheck/deriver/test_qualified_names.ml", lines 6-7, characters 0-20:
6 | type t = Q.t
7 |  [@@deriving qcheck]
Error: Unbound constructor Q.gen

I added the test outside test.mlbecause string comparison doesn't show the difference (let gen = Q.gen in both case). I tried to see if the bug was obvious but I haven't found anything.

@c-cube c-cube added the bug label Dec 1, 2021
@c-cube
Copy link
Owner

c-cube commented Dec 1, 2021

Not sure either, what do you think @vch9 ?

@c-cube
Copy link
Owner

c-cube commented Dec 1, 2021

for reference, the generated code:

module Q =
  struct
    type t = int[@@deriving qcheck]
    include
      struct let _ = fun (_ : t) -> ()
             let gen = QCheck.Gen.int
             let _ = gen end[@@ocaml.doc "@inline"][@@merlin.hide ]
  end
type t = Q.t[@@deriving qcheck]
include struct let _ = fun (_ : t) -> ()
               let gen = Q.gen
               let _ = gen end[@@ocaml.doc "@inline"][@@merlin.hide ]

@vch9
Copy link
Contributor

vch9 commented Dec 1, 2021

Qualified type are currently concatenated into a unique identifier, so it becomes a constructor:

Yes this is a bug, thank you for reporting it. I translated Module.gen to a Pexp_construct where it should be a Pexp_ident.

I tried to see if the bug was obvious but I haven't found anything.

Based on my last discovery, the bug is pretty much easy to fix. We can begin by having a function which create an identifier for a qualified type:

let name_lg = function
  | Lident s -> name s
  | Ldot (lg, s) -> longident_to_str lg ^ "." ^ name s (* Q.t becomes Q.gen *)
  | Lapply _ -> raise (Invalid_argument "We do not produce gen name for Lapply")

Then we change the precedent creation of generator from

let gen ~loc ?(env = TypeGen.empty) lg =
  let (module A) = Ast_builder.make loc in
  match lg with
  | Lident s ->
      Option.value ~default:(name s |> A.evar) @@ TypeGen.find_opt s env
  | Ldot (lg, s) -> A.(pexp_construct (Located.mk @@ Ldot (lg, name s)) None)
  | Lapply (_, _) -> raise (Invalid_argument "gen received an Lapply")

to

let gen ~loc ?(env = TypeGen.empty) lg =
  let (module A) = Ast_builder.make loc in
  let s = longident_to_str lg in
  let name = name_lg lg in
  Option.value ~default:(A.evar name) @@ TypeGen.find_opt s env

Adding a regressing test is a good idea (I should already have done it tbh). What would be more convenient, put our trust in the compiler ? put regression tests on the generated code ?
This last seems complicated in particular cases like this one:

for reference, the generated code:

module Q =
  struct
    type t = int[@@deriving qcheck]
    include
      struct let _ = fun (_ : t) -> ()
             let gen = QCheck.Gen.int
             let _ = gen end[@@ocaml.doc "@inline"][@@merlin.hide ]
  end
type t = Q.t[@@deriving qcheck]
include struct let _ = fun (_ : t) -> ()
               let gen = Q.gen
               let _ = gen end[@@ocaml.doc "@inline"][@@merlin.hide ]

it would not catch the difference between a Pexp_construct and a Pexp_ident.

@bobot
Copy link
Contributor Author

bobot commented Dec 1, 2021

Thanks for finding the erroneous pexp_constructor. But I don't understand your fix. I prefer not to convert the identifier to string. I pushed a fix.

@vch9
Copy link
Contributor

vch9 commented Dec 1, 2021

But I don't understand your fix. I prefer not to convert the identifier to string. I pushed a fix.

I also prefer your fix :)

Maybe we could have a test such as

module A = struct
   type a = (int [@gen QCheck.Gen.pure 0])
    [@@deriving qcheck]

  module B = struct
    type b = (int [@gen QCheck.Gen.pure 1])
    [@@deriving qcheck]
  end
end

type a = A.t
 [@@deriving qcheck]
 
type b = A.B.t
[@@deriving qcheck] 

with a unit (or pbt?) to test assert(QCheck.Gen.generate1 gen_a = 0) and assert(QCheck.Gen.generate1 gen_b = 1)

@bobot
Copy link
Contributor Author

bobot commented Dec 2, 2021

Adding more tests is a good idea, you can push in the branch, but It also could go in another MR. This MR has a fix and a regresssion test.

Is the falling test normal?

@vch9
Copy link
Contributor

vch9 commented Dec 2, 2021

Adding more tests is a good idea, you can push in the branch, but It also could go in another MR.

Unfortunately I can't, I'm not a QCheck's maintainer. This will be done in a follow-up MR.

@c-cube
Copy link
Owner

c-cube commented Dec 2, 2021

I don't think anyone can push onto your branch, @bobot, it's from your fork :)

@vch9
Copy link
Contributor

vch9 commented Dec 2, 2021

I don't think anyone can push onto your branch, @bobot, it's from your fork :)

Can't we on github allow modifications from maintainers?

@c-cube
Copy link
Owner

c-cube commented Dec 2, 2021

Maybe, but I've never understood how to push on such a branch 😅

@bobot bobot changed the title [WIP] Add regression tests for qualified type Add regression tests for qualified type Dec 3, 2021
@bobot
Copy link
Contributor Author

bobot commented Dec 3, 2021

The last time I did that I believe I just added the remote of the branch author. But except for the failing test the branch is done for me, and I don't understand why the test is failing.

@vch9
Copy link
Contributor

vch9 commented Dec 3, 2021

Rebase on master, #203 should fix the test.

@bobot bobot force-pushed the deriver_qualified_name branch from 63e23e4 to fac2c39 Compare December 3, 2021 13:50
@vch9
Copy link
Contributor

vch9 commented Dec 3, 2021

LGTM, thank you for the fix :)

@vch9
Copy link
Contributor

vch9 commented Dec 3, 2021

@c-cube If you also agree we could merge this

@c-cube c-cube merged commit 7787b6e into c-cube:master Dec 3, 2021
@c-cube
Copy link
Owner

c-cube commented Dec 3, 2021

let's go!

@bobot
Copy link
Contributor Author

bobot commented Apr 2, 2022

Is there a release planned?

@c-cube
Copy link
Owner

c-cube commented Apr 3, 2022

I kind of lost context, but I think there were just a few PRs blocking 0.19, and @jmid is going through them like a hurricane 😁

@jmid
Copy link
Collaborator

jmid commented Apr 3, 2022

I most likely lost track myself! Feel free to ping me on any blocking PRs that need my input.

I've spent my weekend spring cleaning PRs #172 #174 #176 #177 to avoid bit rot. Input on #233 #234 #235 is therefore welcome!

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

Successfully merging this pull request may close these issues.

4 participants