From d959d9018ebb2d22376dfe74f401b78ab39b6383 Mon Sep 17 00:00:00 2001 From: funwithcthulhu <29905917+funwithcthulhu@users.noreply.github.com> Date: Wed, 6 May 2026 15:47:50 -0700 Subject: [PATCH 1/2] Confirm reflowed file formatting From 5851d52e63a2255c0a6de81af402baafefa37409 Mon Sep 17 00:00:00 2001 From: funwithcthulhu <29905917+funwithcthulhu@users.noreply.github.com> Date: Wed, 6 May 2026 15:59:52 -0700 Subject: [PATCH 2/2] Reflow source, metadata, and documentation --- .ocamlformat | 1 + CHANGES.md | 4 ++-- README.md | 10 ++++---- RELEASE.md | 19 +++++++-------- bin/main.ml | 13 ++++++---- doctor.opam | 1 + dune-project | 1 + lib/check.ml | 33 +++++++++++++++---------- lib/editor.ml | 14 +++++++---- lib/opam.ml | 52 ++++++++++++++++++++++++++-------------- lib/platform.ml | 14 +++++++---- lib/process.ml | 20 ++++++++++++---- lib/report.ml | 14 +++++++---- test/test_cli.ml | 6 +++-- test/test_diagnostics.ml | 36 +++++++++++++++++++--------- test/test_process.ml | 9 ++++--- test/test_report.ml | 25 +++++++++++-------- 17 files changed, 174 insertions(+), 98 deletions(-) diff --git a/.ocamlformat b/.ocamlformat index aa6f76e..fe2a1d7 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1,2 +1,3 @@ profile = conventional version = 0.29.0 +margin = 72 diff --git a/CHANGES.md b/CHANGES.md index 05f36f0..0d9e95b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,6 @@ ## 0.1.0 - 2026-05-06 - Initial opam release. -- Add `doctor check` with diagnostics for common OCaml, opam, dune, LSP, - formatter, PATH, and editor setup issues. +- Add `doctor check` with diagnostics for common OCaml, opam, dune, LSP, formatter, + PATH, and editor setup issues. - Document the text report and exit codes. diff --git a/README.md b/README.md index d946ffa..8e9cff3 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ `doctor` is a read-only CLI for checking whether a local OCaml development environment looks usable. -It reports missing core tools, opam initialization and switch state, likely -shell environment mismatches, selected opam packages, and the VS Code OCaml -Platform extension when the `code` command is available. +It reports missing core tools, opam initialization and switch state, likely shell +environment mismatches, selected opam packages, and the VS Code OCaml Platform +extension when the `code` command is available. ## Installation @@ -83,7 +83,7 @@ opam exec -- dune runtest opam exec -- dune exec doctor -- check ``` -Tests fake process execution, so they do not depend on the host opam setup, VS -Code, or a particular shell. +Tests fake process execution, so they do not depend on the host opam setup, VS Code, +or a particular shell. Maintainer release notes are in [RELEASE.md](RELEASE.md). diff --git a/RELEASE.md b/RELEASE.md index cff068a..241530e 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,7 +1,7 @@ # Release Process -Notes for publishing `doctor` to opam-repository. This is a release checklist, -not release automation. +Notes for publishing `doctor` to opam-repository. +This is a release checklist, not release automation. Run from a clean checkout. Replace `0.1.0` with the version being released. @@ -30,8 +30,8 @@ opam pin remove doctor -y ## Tag -Commit the release metadata, then create the tag. Push the branch and tag after -checking the final diff. +Commit the release metadata, then create the tag. +Push the branch and tag after checking the final diff. ```console git status --short @@ -40,9 +40,9 @@ git tag -a 0.1.0 -m "Release 0.1.0" ## Publish -Before the first release, verify current `opam-publish` usage with the installed -help or the current opam documentation. The tool is used to open the -opam-repository pull request for the tagged release. +Before the first release, verify current `opam-publish` usage with the installed help +or the current opam documentation. The tool is used to open the opam-repository pull +request for the tagged release. ```console opam install opam-publish @@ -59,6 +59,5 @@ doctor version doctor check ``` -The package metadata currently uses the maintainer's GitHub noreply address. -Change it only when you intentionally want a different public maintainer address -on opam. +The package metadata currently uses the maintainer's GitHub noreply address. Change +it only when you intentionally want a different public maintainer address on opam. diff --git a/bin/main.ml b/bin/main.ml index 65a2e6f..bc0de8e 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -29,7 +29,9 @@ let exit_infos = Cmd.Exit.info ~doc:"one or more errors." 2; Cmd.Exit.info ~doc:"unexpected internal failure." 3; ] - @ List.filter (fun info -> Cmd.Exit.info_code info <> 0) Cmd.Exit.defaults + @ List.filter + (fun info -> Cmd.Exit.info_code info <> 0) + Cmd.Exit.defaults let check_cmd = let doc = "Run OCaml development environment diagnostics." in @@ -43,15 +45,16 @@ let version_cmd = let default_cmd = let doc = - "Inspect an OCaml development environment and print actionable diagnostics." + "Inspect an OCaml development environment and print actionable \ + diagnostics." in let man = [ `S Manpage.s_description; `P - "doctor checks for common OCaml, opam, dune, LSP, formatter, shell \ - environment, and VS Code setup issues. It does not modify your \ - machine."; + "doctor checks for common OCaml, opam, dune, LSP, formatter, \ + shell environment, and VS Code setup issues. It does not \ + modify your machine."; ] in Cmd.group diff --git a/doctor.opam b/doctor.opam index dc99ecb..27cbe15 100644 --- a/doctor.opam +++ b/doctor.opam @@ -9,6 +9,7 @@ and editor integration hints. maintainer: "Thomas B. <29905917+funwithcthulhu@users.noreply.github.com>" authors: "Thomas B." + license: "MIT" tags: [ diff --git a/dune-project b/dune-project index 2a04a31..da1e201 100644 --- a/dune-project +++ b/dune-project @@ -8,6 +8,7 @@ (authors "Thomas B.") (license MIT) + (maintainers "Thomas B. <29905917+funwithcthulhu@users.noreply.github.com>") (package diff --git a/lib/check.ml b/lib/check.ml index deb22da..98e93f0 100644 --- a/lib/check.ml +++ b/lib/check.ml @@ -24,14 +24,17 @@ let max_severity left right = let aggregate diagnostics = List.fold_left - (fun severity diagnostic -> max_severity severity diagnostic.severity) + (fun severity diagnostic -> + max_severity severity diagnostic.severity) Ok diagnostics let exit_code diagnostics = match aggregate diagnostics with Ok -> 0 | Warn -> 1 | Error -> 2 let clean_output output = - output |> String.split_on_char '\n' |> List.map String.trim + output + |> String.split_on_char '\n' + |> List.map String.trim |> List.filter (fun line -> line <> "") let first_output_line (result : Process.result) = @@ -86,14 +89,16 @@ let command_diagnostic ~(run : Process.runner) spec = make ~id:("command." ^ spec.command) ~title:(Printf.sprintf "%s command failed" spec.label) - ~detail:(Process.summary result) ~suggestion:spec.missing_suggestion - spec.missing_severity + ~detail:(Process.summary result) + ~suggestion:spec.missing_suggestion spec.missing_severity let lsp_command_diagnostic ~(run : Process.runner) = let primary = run "ocaml-lsp-server" [ "--version" ] in match primary.status with | Process.Exited 0 -> - let version = primary |> first_output_line |> Option.map String.trim in + let version = + primary |> first_output_line |> Option.map String.trim + in let title = title_with_version "OCaml LSP" version in make ~id:"command.ocaml-lsp-server" ~title Ok | Process.Spawn_error _ -> ( @@ -114,24 +119,25 @@ let lsp_command_diagnostic ~(run : Process.runner) = make ~id:"command.ocaml-lsp-server" ~title:"OCaml LSP command not found" ~detail: - "Checked `ocaml-lsp-server` and `ocamllsp`; neither command is \ - available on PATH." + "Checked `ocaml-lsp-server` and `ocamllsp`; neither \ + command is available on PATH." ~suggestion:"opam install ocaml-lsp-server" Warn | _ -> make ~id:"command.ocaml-lsp-server" ~title:"OCaml LSP found, but its version could not be read" ~detail:(Process.summary fallback) ~suggestion: - "Try running `ocamllsp --version` directly, or reinstall it with \ - opam." + "Try running `ocamllsp --version` directly, or reinstall \ + it with opam." Warn) | _ -> make ~id:"command.ocaml-lsp-server" - ~title:"ocaml-lsp-server found, but its version could not be read" + ~title: + "ocaml-lsp-server found, but its version could not be read" ~detail:(Process.summary primary) ~suggestion: - "Try running `ocaml-lsp-server --version` directly, or reinstall it \ - with opam." + "Try running `ocaml-lsp-server --version` directly, or \ + reinstall it with opam." Warn let command_diagnostics ~run = @@ -151,7 +157,8 @@ let command_diagnostics ~run = label = "OCaml"; missing_severity = Error; missing_suggestion = - "Create or select an opam switch, then sync your shell environment."; + "Create or select an opam switch, then sync your shell \ + environment."; version_parser = parse_ocaml_version; }; { diff --git a/lib/editor.ml b/lib/editor.ml index 0b7bbe3..0f6aed8 100644 --- a/lib/editor.ml +++ b/lib/editor.ml @@ -1,5 +1,7 @@ let has_extension extensions extension = - extensions |> String.split_on_char '\n' |> List.map String.trim + extensions + |> String.split_on_char '\n' + |> List.map String.trim |> List.exists (String.equal extension) let diagnostics ~(run : Process.runner) = @@ -14,10 +16,12 @@ let diagnostics ~(run : Process.runner) = let extensions = run "code" [ "--list-extensions" ] in match extensions.status with | Process.Exited 0 - when has_extension extensions.stdout "ocamllabs.ocaml-platform" -> + when has_extension extensions.stdout "ocamllabs.ocaml-platform" + -> [ Check.make ~id:"editor.vscode.ocaml-platform" - ~title:"VS Code OCaml Platform extension detected" Check.Ok; + ~title:"VS Code OCaml Platform extension detected" + Check.Ok; ] | Process.Exited 0 -> [ @@ -33,8 +37,8 @@ let diagnostics ~(run : Process.runner) = ~title:"could not list VS Code extensions" ~detail:(Process.summary extensions) ~suggestion: - "Open VS Code and check whether ocamllabs.ocaml-platform is \ - installed." + "Open VS Code and check whether \ + ocamllabs.ocaml-platform is installed." Check.Warn; ]) | _ -> diff --git a/lib/opam.ml b/lib/opam.ml index 1857a0d..6453960 100644 --- a/lib/opam.ml +++ b/lib/opam.ml @@ -1,5 +1,7 @@ let non_empty_lines output = - output |> String.split_on_char '\n' |> List.map String.trim + output + |> String.split_on_char '\n' + |> List.map String.trim |> List.filter (fun line -> line <> "") let parse_active_switch output = @@ -7,7 +9,8 @@ let parse_active_switch output = | [] -> None | line :: _ -> let lower = String.lowercase_ascii line in - if String.length lower >= 7 && String.sub lower 0 7 = "[error]" then None + if String.length lower >= 7 && String.sub lower 0 7 = "[error]" + then None else Some line let parse_switch_list output = @@ -30,7 +33,8 @@ let parse_installed_packages output = |> List.map (fun line -> match words line with package :: _ -> package | [] -> line) -let has_package packages package = List.exists (String.equal package) packages +let has_package packages package = + List.exists (String.equal package) packages let opam_available ~(run : Process.runner) = match (run "opam" [ "--version" ]).status with @@ -47,12 +51,15 @@ let initialized_diagnostic ~(run : Process.runner) = ~detail:(Printf.sprintf "Root: %s" root) Check.Ok | [] -> - Check.make ~id:"opam.initialized" ~title:"opam root could not be read" - ~detail:(Process.summary result) ~suggestion:"opam init" Check.Warn) + Check.make ~id:"opam.initialized" + ~title:"opam root could not be read" + ~detail:(Process.summary result) + ~suggestion:"opam init" Check.Warn) | _ -> Check.make ~id:"opam.initialized" ~title:"opam does not appear initialized" - ~detail:(Process.summary result) ~suggestion:"opam init" Check.Warn + ~detail:(Process.summary result) + ~suggestion:"opam init" Check.Warn let switch_diagnostics ~(run : Process.runner) os = let show = run "opam" [ "switch"; "show" ] in @@ -75,16 +82,18 @@ let switch_diagnostics ~(run : Process.runner) os = if switch_list = [] then "opam switch create 5.2.0" else Platform.environment_sync_suggestion os in - Check.make ~id:"opam.switch.active" ~title:"opam switch not active" - ~detail:"opam did not report an active switch." ~suggestion - Check.Error) + Check.make ~id:"opam.switch.active" + ~title:"opam switch not active" + ~detail:"opam did not report an active switch." + ~suggestion Check.Error) | _ -> let suggestion = if switch_list = [] then "opam switch create 5.2.0" else Platform.environment_sync_suggestion os in - Check.make ~id:"opam.switch.active" ~title:"opam switch not active" - ~detail:(Process.summary show) ~suggestion Check.Error + Check.make ~id:"opam.switch.active" + ~title:"opam switch not active" ~detail:(Process.summary show) + ~suggestion Check.Error in let list_diagnostic = match switches.status with @@ -99,7 +108,8 @@ let switch_diagnostics ~(run : Process.runner) os = ~title:(Printf.sprintf "opam switches available: %d" count) ?detail Check.Ok | _ -> - Check.make ~id:"opam.switch.list" ~title:"could not list opam switches" + Check.make ~id:"opam.switch.list" + ~title:"could not list opam switches" ~detail:(Process.summary switches) ~suggestion:"Run `opam switch list` to inspect your switches." Check.Warn @@ -124,7 +134,8 @@ let switch_bin_diagnostic ~(run : Process.runner) os = | _ -> None in match first_path with - | Some path when Platform.is_path_under ~parent:switch_bin path -> + | Some path + when Platform.is_path_under ~parent:switch_bin path -> [ Check.make ~id:"opam.env.sync" ~title:"shell environment appears synced with opam" @@ -134,10 +145,12 @@ let switch_bin_diagnostic ~(run : Process.runner) os = | Some path -> [ Check.make ~id:"opam.env.sync" - ~title:"shell environment may be out of sync with opam" + ~title: + "shell environment may be out of sync with opam" ~detail: (Printf.sprintf - "ocaml resolves to %s, but the active switch bin is %s." + "ocaml resolves to %s, but the active switch \ + bin is %s." path switch_bin) ~suggestion:(Platform.environment_sync_suggestion os) Check.Warn; @@ -153,7 +166,8 @@ let package_diagnostic packages package ~optional = Check.Ok else let title = - if optional then Printf.sprintf "%s not installed (optional)" package + if optional then + Printf.sprintf "%s not installed (optional)" package else Printf.sprintf "%s not installed" package in Check.make @@ -178,7 +192,8 @@ let package_diagnostics ~(run : Process.runner) = Check.make ~id:"opam.packages" ~title:"could not read installed opam packages" ~detail:(Process.summary result) - ~suggestion:"Run `opam list --installed --short` to inspect packages." + ~suggestion: + "Run `opam list --installed --short` to inspect packages." Check.Warn; ] @@ -192,6 +207,7 @@ let diagnostics ~(run : Process.runner) os = [ Check.make ~id:"opam.initialized" ~title:"opam checks skipped because opam is missing" - ~suggestion:"Install opam from https://opam.ocaml.org/doc/Install.html" + ~suggestion: + "Install opam from https://opam.ocaml.org/doc/Install.html" Check.Error; ] diff --git a/lib/platform.ml b/lib/platform.ml index e14338c..37db098 100644 --- a/lib/platform.ml +++ b/lib/platform.ml @@ -23,7 +23,8 @@ let file_contains path needle = let rec loop () = match input_line channel with | line -> - contains_substring (String.lowercase_ascii line) needle || loop () + contains_substring (String.lowercase_ascii line) needle + || loop () | exception End_of_file -> false in loop ()) @@ -70,18 +71,21 @@ let unix_like_shell = function let environment_sync_suggestion os = if unix_like_shell os then "eval $(opam env)" else - "Run `opam env` and apply the environment changes in your current shell, \ - then restart the terminal if needed." + "Run `opam env` and apply the environment changes in your current \ + shell, then restart the terminal if needed." let normalize_path path = - let path = String.trim path |> String.map (function '\\' -> '/' | c -> c) in + let path = + String.trim path |> String.map (function '\\' -> '/' | c -> c) + in if Sys.win32 then String.lowercase_ascii path else path let is_path_under ~parent path = let parent = normalize_path parent in let path = normalize_path path in let parent = - if parent <> "" && parent.[String.length parent - 1] = '/' then parent + if parent <> "" && parent.[String.length parent - 1] = '/' then + parent else parent ^ "/" in String.length path >= String.length parent diff --git a/lib/process.ml b/lib/process.ml index 1048257..15e1c08 100644 --- a/lib/process.ml +++ b/lib/process.ml @@ -77,7 +77,8 @@ let run command args = let argv = Array.of_list (command :: args) in let env = Unix.environment () in let pid = - Unix.create_process_env command argv env stdin_fd stdout_fd stderr_fd + Unix.create_process_env command argv env stdin_fd stdout_fd + stderr_fd in close_noerr stdin_fd; close_noerr stdout_fd; @@ -87,16 +88,25 @@ let run command args = let stderr = read_file stderr_path in remove_if_exists stdout_path; remove_if_exists stderr_path; - { command; args; status = unix_status_to_status status; stdout; stderr } + { + command; + args; + status = unix_status_to_status status; + stdout; + stderr; + } with Unix.Unix_error (error, function_name, argument) -> let message = - Printf.sprintf "%s: %s %s" (Unix.error_message error) function_name - argument + Printf.sprintf "%s: %s %s" + (Unix.error_message error) + function_name argument in finish (Spawn_error message) let trim_for_summary text = - text |> String.split_on_char '\n' |> List.map String.trim + text + |> String.split_on_char '\n' + |> List.map String.trim |> List.filter (fun line -> line <> "") |> String.concat " " diff --git a/lib/report.ml b/lib/report.ml index d43e9b1..b4e27aa 100644 --- a/lib/report.ml +++ b/lib/report.ml @@ -1,18 +1,23 @@ let indent_for status = String.make (String.length status + 3) ' ' let non_empty_lines text = - text |> String.split_on_char '\n' |> List.map String.trim + text + |> String.split_on_char '\n' + |> List.map String.trim |> List.filter (fun line -> line <> "") let format_extra_lines indent ~prefix text = match non_empty_lines text with | [] -> [] | first :: rest -> - (indent ^ prefix ^ first) :: List.map (fun line -> indent ^ line) rest + (indent ^ prefix ^ first) + :: List.map (fun line -> indent ^ line) rest let format_diagnostic diagnostic = let status = Check.severity_to_string diagnostic.Check.severity in - let first_line = Printf.sprintf "[%s] %s" status diagnostic.Check.title in + let first_line = + Printf.sprintf "[%s] %s" status diagnostic.Check.title + in let indent = indent_for status in let extra = (match diagnostic.detail with @@ -45,7 +50,8 @@ let render diagnostics = | [] -> "No diagnostics." | _ -> (diagnostics |> List.map format_diagnostic |> String.concat "\n") - ^ "\n\n" ^ format_summary diagnostics + ^ "\n\n" + ^ format_summary diagnostics in "OCaml Doctor\n\n" ^ body ^ "\n" diff --git a/test/test_cli.ml b/test/test_cli.ml index 345f3d7..d93797c 100644 --- a/test/test_cli.ml +++ b/test/test_cli.ml @@ -1,5 +1,7 @@ let expect_equal label expected actual = if not (String.equal expected actual) then - failwith (Printf.sprintf "%s: expected %S, got %S" label expected actual) + failwith + (Printf.sprintf "%s: expected %S, got %S" label expected actual) -let () = expect_equal "version display" "doctor 0.1.0" Doctor.Version.display +let () = + expect_equal "version display" "doctor 0.1.0" Doctor.Version.display diff --git a/test/test_diagnostics.ml b/test/test_diagnostics.ml index d53510d..a8bbfd9 100644 --- a/test/test_diagnostics.ml +++ b/test/test_diagnostics.ml @@ -9,12 +9,14 @@ let result ?(stdout = "") ?(stderr = "") status command args = let run responses command args = match List.assoc_opt (command, args) responses with - | Some (status, stdout, stderr) -> result ~stdout ~stderr status command args + | Some (status, stdout, stderr) -> + result ~stdout ~stderr status command args | None -> result (Process.Spawn_error "not found") command args let expect_equal label expected actual = if not (String.equal expected actual) then - failwith (Printf.sprintf "%s: expected %S, got %S" label expected actual) + failwith + (Printf.sprintf "%s: expected %S, got %S" label expected actual) let expect_severity label expected actual = if expected <> actual then @@ -26,7 +28,8 @@ let expect_some label = function let find_diagnostic id diagnostics = diagnostics - |> List.find_opt (fun diagnostic -> String.equal diagnostic.Check.id id) + |> List.find_opt (fun diagnostic -> + String.equal diagnostic.Check.id id) |> expect_some ("diagnostic " ^ id) let () = @@ -39,10 +42,13 @@ let () = ( ("ocaml-lsp-server", [ "--version" ]), (Process.Spawn_error "not found", "", "") ); (("ocamllsp", [ "--version" ]), (Process.Exited 0, "1.26.0\n", "")); - (("ocamlformat", [ "--version" ]), (Process.Exited 0, "0.27.0\n", "")); + ( ("ocamlformat", [ "--version" ]), + (Process.Exited 0, "0.27.0\n", "") ); ] in - let diagnostics = Check.command_diagnostics ~run:(run command_responses) in + let diagnostics = + Check.command_diagnostics ~run:(run command_responses) + in let lsp = find_diagnostic "command.ocaml-lsp-server" diagnostics in expect_severity "lsp fallback" Check.Ok lsp.severity; expect_equal "lsp fallback title" "OCaml LSP found: 1.26.0 (ocamllsp)" @@ -61,13 +67,15 @@ let () = expect_severity "missing command is warning" Check.Warn missing_ocamlformat.severity; expect_equal "missing command suggestion" "opam install ocamlformat" - (expect_some "missing command suggestion" missing_ocamlformat.suggestion); + (expect_some "missing command suggestion" + missing_ocamlformat.suggestion); let failing_opam = Check.command_diagnostic ~run: (run [ - (("opam", [ "--version" ]), (Process.Exited 2, "", "opam failed\n")); + ( ("opam", [ "--version" ]), + (Process.Exited 2, "", "opam failed\n") ); ]) { command = "opam"; @@ -85,7 +93,8 @@ let () = let opam_responses = [ (("opam", [ "--version" ]), (Process.Exited 0, "2.2.1\n", "")); - (("opam", [ "var"; "root" ]), (Process.Exited 0, "/home/me/.opam\n", "")); + ( ("opam", [ "var"; "root" ]), + (Process.Exited 0, "/home/me/.opam\n", "") ); (("opam", [ "switch"; "show" ]), (Process.Exited 0, "5.2.0\n", "")); ( ("opam", [ "switch"; "list"; "--short" ]), (Process.Exited 0, "default\n5.2.0\n", "") ); @@ -97,13 +106,18 @@ let () = (Process.Exited 0, "ocaml\ndune\nocaml-lsp-server\n", "") ); ] in - let diagnostics = Opam.diagnostics ~run:(run opam_responses) Platform.Linux in + let diagnostics = + Opam.diagnostics ~run:(run opam_responses) Platform.Linux + in let env = find_diagnostic "opam.env.sync" diagnostics in expect_severity "env sync warning" Check.Warn env.severity; expect_equal "env sync suggestion" "eval $(opam env)" (expect_some "env sync suggestion" env.suggestion); - let ocamlformat = find_diagnostic "opam.package.ocamlformat" diagnostics in - expect_severity "missing ocamlformat package" Check.Warn ocamlformat.severity; + let ocamlformat = + find_diagnostic "opam.package.ocamlformat" diagnostics + in + expect_severity "missing ocamlformat package" Check.Warn + ocamlformat.severity; let editor = Editor.diagnostics ~run:(run []) in let code = find_diagnostic "editor.vscode.command" editor in diff --git a/test/test_process.ml b/test/test_process.ml index cff5ca4..a4e9218 100644 --- a/test/test_process.ml +++ b/test/test_process.ml @@ -1,6 +1,7 @@ let expect_equal label expected actual = if not (String.equal expected actual) then - failwith (Printf.sprintf "%s: expected %S, got %S" label expected actual) + failwith + (Printf.sprintf "%s: expected %S, got %S" label expected actual) let expect_bool label value = if not value then failwith (Printf.sprintf "%s: expected true" label) @@ -13,7 +14,8 @@ let () = expect_equal "command line quoting" "opam \"switch show\"" (Doctor.Process.command_line "opam" [ "switch show" ]); expect_equal "ocaml version parsing" "5.2.0" - (Doctor.Check.parse_ocaml_version "The OCaml toplevel, version 5.2.0"); + (Doctor.Check.parse_ocaml_version + "The OCaml toplevel, version 5.2.0"); expect_equal "active switch parsing" "5.2.0" (expect_some "active switch parsing" (Doctor.Opam.parse_active_switch "5.2.0\n")); @@ -24,7 +26,8 @@ let () = "ocaml\nbase-unix\ndune\nocaml-lsp-server\n" |> fun packages -> Doctor.Opam.has_package packages "dune" ); expect_equal "switch list parser" "default, 5.2.0" - (Doctor.Opam.parse_switch_list "default\n5.2.0\n" |> String.concat ", "); + (Doctor.Opam.parse_switch_list "default\n5.2.0\n" + |> String.concat ", "); expect_equal "package parser trims whitespace" "dune, ocamlformat" (Doctor.Opam.parse_installed_packages " dune 3.17.0\n\tocamlformat\t0.27.0\n" diff --git a/test/test_report.ml b/test/test_report.ml index 0f2fa93..3d47a80 100644 --- a/test/test_report.ml +++ b/test/test_report.ml @@ -1,14 +1,17 @@ let diagnostic severity title = - Doctor.Check.make ~id:title ~title ~suggestion:"opam install ocamlformat" - severity + Doctor.Check.make ~id:title ~title + ~suggestion:"opam install ocamlformat" severity let expect_equal label expected actual = if expected <> actual then - failwith (Printf.sprintf "%s: expected %d, got %d" label expected actual) + failwith + (Printf.sprintf "%s: expected %d, got %d" label expected actual) let expect_line label needle haystack = if - not (List.exists (String.equal needle) (String.split_on_char '\n' haystack)) + not + (List.exists (String.equal needle) + (String.split_on_char '\n' haystack)) then failwith (Printf.sprintf "%s: missing line %S" label needle) let () = @@ -16,15 +19,17 @@ let () = let warn = diagnostic Doctor.Check.Warn "ocamlformat not installed" in let error = diagnostic Doctor.Check.Error "opam switch not active" in expect_equal "ok exit code" 0 (Doctor.Report.exit_code [ ok ]); - expect_equal "warning exit code" 1 (Doctor.Report.exit_code [ ok; warn ]); - expect_equal "error exit code" 2 (Doctor.Report.exit_code [ ok; warn; error ]); + expect_equal "warning exit code" 1 + (Doctor.Report.exit_code [ ok; warn ]); + expect_equal "error exit code" 2 + (Doctor.Report.exit_code [ ok; warn; error ]); expect_equal "summary ok count" 1 (let ok_count, _, _ = Doctor.Report.counts [ ok; warn; error ] in ok_count); let rendered = Doctor.Report.render [ warn ] in expect_line "warning line" "[WARN] ocamlformat not installed" rendered; - expect_line "suggestion line" " Suggested fix: opam install ocamlformat" - rendered; + expect_line "suggestion line" + " Suggested fix: opam install ocamlformat" rendered; expect_line "summary line" "Summary: 0 OK, 1 WARN, 0 ERROR" rendered; let multiline = Doctor.Check.make ~id:"multi" ~title:"multi-line detail" @@ -34,6 +39,6 @@ let () = let rendered = Doctor.Report.render [ multiline ] in expect_line "multiline detail first" " first line" rendered; expect_line "multiline detail second" " second line" rendered; - expect_line "multiline suggestion first" " Suggested fix: fix it" - rendered; + expect_line "multiline suggestion first" + " Suggested fix: fix it" rendered; expect_line "multiline suggestion second" " try again" rendered