From 20c5abba2f762e917503e3d613729f12607baf88 Mon Sep 17 00:00:00 2001 From: Marc Coquand Date: Fri, 12 Jan 2024 08:01:25 -0600 Subject: Implement support for dates --- README.md | 9 +++++++++ dune-project | 10 +++++++++- fixgen.opam | 1 + flake.nix | 15 +++++++-------- lib/ast_types.ml | 15 +++++++++++++++ lib/dune | 2 ++ lib/fixture.ml | 17 ++++++++++++++++- lib/lexer.mll | 3 +++ lib/parser.mly | 12 ++++++++++++ test/test_parser.ml | 3 +++ 10 files changed, 77 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f48fd88..b348a70 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,15 @@ frank2 walter3 ``` +- Dates (Future, Present, Past) + +```sh +$ fixgen '_(2): created_at past' +created_at +2001-07-19T18:35:13+00:00 +2011-06-21T04:31:47+00:00 +``` + ## Development - Prerequisites - [Nix](https://nixos.org/manual/nix/stable/installation/installing-binary) diff --git a/dune-project b/dune-project index 6b155aa..41e4a37 100644 --- a/dune-project +++ b/dune-project @@ -18,7 +18,15 @@ (name fixgen) (synopsis "Generate fixtures for testing") (description "Generate fixtures for testing") - (depends ocaml dune ppx_inline_test ppx_deriving uuidm alcotest cmdliner + (depends + ocaml + dune + ppx_inline_test + ppx_deriving + uuidm + alcotest + cmdliner + ISO8601 ) ) diff --git a/fixgen.opam b/fixgen.opam index 988b773..dab8f87 100644 --- a/fixgen.opam +++ b/fixgen.opam @@ -14,6 +14,7 @@ depends: [ "uuidm" "alcotest" "cmdliner" + "ISO8601" "odoc" {with-doc} ] build: [ diff --git a/flake.nix b/flake.nix index 5801f07..24abbb7 100644 --- a/flake.nix +++ b/flake.nix @@ -9,29 +9,28 @@ let package = "fixgen"; in flake-utils.lib.eachDefaultSystem (system: let + sourceRoot = "."; pkgs = nixpkgs.legacyPackages.${system}; on = opam-nix.lib.${system}; devPackagesQuery = { - # You can add "development" packages here. They will get added to the devShell automatically. ocaml-lsp-server = "*"; ocamlformat = "*"; ocamlfind = "1.9.5"; utop = "*"; }; query = devPackagesQuery // { - ## You can force versions of certain packages here, e.g: - ## - force the ocaml compiler to be taken from opam-repository: ocaml-base-compiler = "*"; - ## - or force the compiler to be taken from nixpkgs and be a certain version: - # ocaml-system = "4.14.0"; - ## - or force ocamlfind to be a certain version: }; scope = on.buildOpamProject' { } ./. query; overlay = final: prev: { # You can add overrides here + # Handles unpacker produced multiple directories error + timedesc-tzdb = prev.timedesc-tzdb.overrideAttrs (_: { sourceRoot = "."; }); + timedesc-tzlocal = prev.timedesc-tzdb.overrideAttrs (_: { sourceRoot = "."; }); + timedesc = prev.timedesc-tzdb.overrideAttrs (_: { sourceRoot = "."; }); + timedesc-sexp = prev.timedesc-tzdb.overrideAttrs (_: { sourceRoot = "."; }); + timere = prev.timedesc-tzdb.overrideAttrs (_: { sourceRoot = "."; }); ${package} = prev.${package}.overrideAttrs (_: { - # Prevent the ocaml dependencies from leaking into dependent environments - doNixSupport = false; }); }; scope' = scope.overrideScope' overlay; diff --git a/lib/ast_types.ml b/lib/ast_types.ml index 0a4c05d..95baea5 100644 --- a/lib/ast_types.ml +++ b/lib/ast_types.ml @@ -11,6 +11,9 @@ type ast_row = | List of string * string list * ast_row | Username of string * ast_row | Foreign of string * string * string * ast_row + | Past of string * ast_row + | Future of string * ast_row + | Now of string * ast_row (* parent, row, child_name, row *) | End [@@deriving show, eq] @@ -51,6 +54,15 @@ let rec print_row = function | Email (s, r) -> printf "Email(%s)," s; print_row r + | Past (s, r) -> + printf "Past(%s)," s; + print_row r + | Future (s, r) -> + printf "Future(%s)," s; + print_row r + | Now (s, r) -> + printf "Now(%s)," s; + print_row r | End -> printf "\n" @@ -89,6 +101,9 @@ let rec ast_row_to_fixtures = function | Increment (s, r) -> PColumn (Fixture.Increment s) :: ast_row_to_fixtures r | Email (s, r) -> PColumn (Fixture.Email s) :: ast_row_to_fixtures r | Username (s, r) -> PColumn (Fixture.Username s) :: ast_row_to_fixtures r + | Past (s, r) -> PColumn (Fixture.Past s) :: ast_row_to_fixtures r + | Future (s, r) -> PColumn (Fixture.Future s) :: ast_row_to_fixtures r + | Now (s, r) -> PColumn (Fixture.Now s) :: ast_row_to_fixtures r | End -> [] let extend_table_with_row table row = diff --git a/lib/dune b/lib/dune index 08e5290..a1167ae 100644 --- a/lib/dune +++ b/lib/dune @@ -6,6 +6,8 @@ (library (name fixgen) (libraries + ISO8601 + unix uuidm ) (modules parser lexer ast_types fixture) diff --git a/lib/fixture.ml b/lib/fixture.ml index d34b155..47ae453 100644 --- a/lib/fixture.ml +++ b/lib/fixture.ml @@ -107,6 +107,9 @@ type t = | Increment of string | Const of string * string | Email of string + | Past of string + | Future of string + | Now of string | List of string * string list (* (Name, foreign ids to pick from) *) @@ -121,6 +124,16 @@ let generate_fixture index fixture = | Const (_, value) -> String value | Email _ -> String (random_email str_index ()) | Int (_, min, max) -> Int (Random.int (max - min) + min) + | Past _ -> + let now = Unix.time () in + String (ISO8601.Permissive.string_of_datetimezone (Random.float now, 0.)) + | Future _ -> + let now = Unix.time () in + String + (ISO8601.Permissive.string_of_datetimezone (Random.float (Float.mul now 2.), 0.)) + | Now _ -> + let now = Unix.time () in + String (ISO8601.Permissive.string_of_datetimezone (now, 0.)) | List (_, values) -> String (random_value_in_list values ()) @@ -135,7 +148,6 @@ let%test "random_value_in_list" = (* TODO: Support "hashed" password *) -(* TODO: Support dates *) (* TODO: Support variables using @ *) let rec replicate element n = @@ -160,6 +172,9 @@ let id_of_fixture fixture = | Int (id, _, _) -> id | List (id, _) -> id | Email id -> id + | Past id -> id + | Future id -> id + | Now id -> id in String id diff --git a/lib/lexer.mll b/lib/lexer.mll index 1985c2d..1b24847 100644 --- a/lib/lexer.mll +++ b/lib/lexer.mll @@ -22,6 +22,9 @@ rule read = | "name" { NAME } | "increment" { INCREMENT } | "username" { USERNAME } + | "past" { PAST } + | "future" { FUTURE } + | "now" { NOW } | "int" { INTSYMBOL } | id { IDENTIFIER (Lexing.lexeme lexbuf) } | "(" { LBRACE } diff --git a/lib/parser.mly b/lib/parser.mly index 177daaf..f14550e 100644 --- a/lib/parser.mly +++ b/lib/parser.mly @@ -11,6 +11,9 @@ %token COLON %token DOT %token EOF +%token PAST +%token FUTURE +%token NOW %token INTSYMBOL %token INT %token LBRACE @@ -56,6 +59,15 @@ row: | row_title = id_or_other; EMAIL; COMMA; r = row { Email (row_title, r) } | row_title = id_or_other; EMAIL { Email (row_title, End) } + | row_title = id_or_other; PAST; COMMA; r = row { Past (row_title, r) } + | row_title = id_or_other; PAST { Past (row_title, End) } + + | row_title = id_or_other; FUTURE; COMMA; r = row { Future (row_title, r) } + | row_title = id_or_other; FUTURE { Future (row_title, End) } + + | row_title = id_or_other; NOW; COMMA; r = row { Now (row_title, r) } + | row_title = id_or_other; NOW { Now (row_title, End) } + | row_title = id_or_other; USERNAME; COMMA; r = row { Username (row_title, r) } | row_title = id_or_other; USERNAME { Username (row_title, End) } diff --git a/test/test_parser.ml b/test/test_parser.ml index 057c525..9f7f998 100644 --- a/test/test_parser.ml +++ b/test/test_parser.ml @@ -30,6 +30,9 @@ let rows_suite = ; "Supports incremental index", `Quick, test_parse "purchases_new (5): id increment" ; "Supports username", `Quick, test_parse "_ (5): name username" ; "Supports email", `Quick, test_parse "user (2): email email" + ; "Supports past", `Quick, test_parse "user (2): created_at past" + ; "Supports future", `Quick, test_parse "user (2): ttl future" + ; "Supports now", `Quick, test_parse "user (2): created_at now" ] -- cgit v1.2.3