From 640b4738d04c23ef148dcc664f125d098e8fe1f2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 03:46:35 +0000 Subject: [PATCH 1/3] test: add tests for sys, html and time stdlib modules Add test coverage for three stdlib modules that had bindings but no tests: - TestSys.fs: platform, version, maxsize, maxunicode, path, argv, byteorder - TestHtml.fs: escape (with/without quote flag), unescape, roundtrip - TestTime.fs: time, monotonic, perf_counter, process_time, ctime, sleep, timezone Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- test/Fable.Python.Test.fsproj | 3 +++ test/TestHtml.fs | 41 ++++++++++++++++++++++++++++ test/TestSys.fs | 35 ++++++++++++++++++++++++ test/TestTime.fs | 50 +++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 test/TestHtml.fs create mode 100644 test/TestSys.fs create mode 100644 test/TestTime.fs diff --git a/test/Fable.Python.Test.fsproj b/test/Fable.Python.Test.fsproj index 7b0d3b9..3c439a7 100644 --- a/test/Fable.Python.Test.fsproj +++ b/test/Fable.Python.Test.fsproj @@ -27,6 +27,9 @@ + + + diff --git a/test/TestHtml.fs b/test/TestHtml.fs new file mode 100644 index 0000000..be7d1cf --- /dev/null +++ b/test/TestHtml.fs @@ -0,0 +1,41 @@ +module Fable.Python.Tests.Html + +open Fable.Python.Testing +open Fable.Python.Html + +[] +let ``test html.escape escapes ampersand`` () = + html.escape "a & b" |> equal "a & b" + +[] +let ``test html.escape escapes less-than`` () = + html.escape "" |> equal "<tag>" + +[] +let ``test html.escape escapes double quotes by default`` () = + html.escape "\"hello\"" |> equal ""hello"" + +[] +let ``test html.escape with quote=false leaves quotes unescaped`` () = + html.escape ("\"hello\"", false) |> equal "\"hello\"" + +[] +let ``test html.escape with quote=true escapes quotes`` () = + html.escape ("\"hello\"", true) |> equal ""hello"" + +[] +let ``test html.unescape reverses escape`` () = + html.unescape "<tag>" |> equal "" + +[] +let ``test html.unescape reverses ampersand`` () = + html.unescape "a & b" |> equal "a & b" + +[] +let ``test html.unescape reverses quot`` () = + html.unescape ""hello"" |> equal "\"hello\"" + +[] +let ``test html roundtrip`` () = + let original = "
Hello & World
" + html.unescape (html.escape original) |> equal original diff --git a/test/TestSys.fs b/test/TestSys.fs new file mode 100644 index 0000000..025aca6 --- /dev/null +++ b/test/TestSys.fs @@ -0,0 +1,35 @@ +module Fable.Python.Tests.Sys + +open Fable.Python.Testing +open Fable.Python.Sys + +[] +let ``test sys.platform is non-empty string`` () = + sys.platform.Length > 0 |> equal true + +[] +let ``test sys.version is non-empty string`` () = + sys.version.Length > 0 |> equal true + +[] +let ``test sys.maxsize is large positive int`` () = + sys.maxsize > 0 |> equal true + +[] +let ``test sys.maxunicode is 1114111`` () = + sys.maxunicode |> equal 1114111 + +[] +let ``test sys.path is list`` () = + sys.path |> ignore + sys.path.Count >= 0 |> equal true + +[] +let ``test sys.argv is list`` () = + sys.argv |> ignore + sys.argv.Count >= 0 |> equal true + +[] +let ``test sys.byteorder is little or big`` () = + let order = sys.byteorder + (order = ByteOrder.Little || order = ByteOrder.Big) |> equal true diff --git a/test/TestTime.fs b/test/TestTime.fs new file mode 100644 index 0000000..ccf65ad --- /dev/null +++ b/test/TestTime.fs @@ -0,0 +1,50 @@ +module Fable.Python.Tests.Time + +open Fable.Python.Testing +open Fable.Python.Time + +[] +let ``test time.time returns positive float`` () = + let t = time.time () + t > 0.0 |> equal true + +[] +let ``test time.monotonic returns positive float`` () = + let t = time.monotonic () + t > 0.0 |> equal true + +[] +let ``test time.perf_counter returns positive float`` () = + let t = time.perf_counter () + t > 0.0 |> equal true + +[] +let ``test time.process_time returns non-negative float`` () = + let t = time.process_time () + t >= 0.0 |> equal true + +[] +let ``test time.monotonic increases over calls`` () = + let t1 = time.monotonic () + let t2 = time.monotonic () + t2 >= t1 |> equal true + +[] +let ``test time.ctime returns non-empty string`` () = + let s = time.ctime () + s.Length > 0 |> equal true + +[] +let ``test time.ctime with seconds returns non-empty string`` () = + let s = time.ctime 0.0 + s.Length > 0 |> equal true + +[] +let ``test time.sleep does not throw`` () = + time.sleep 0.0 |> ignore + true |> equal true + +[] +let ``test time.timezone is int`` () = + let tz = time.timezone + (tz >= -50400 && tz <= 50400) |> equal true From aef8090af61f48c942fbe9babc63b2a86354941f Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sat, 18 Apr 2026 06:46:59 +0200 Subject: [PATCH 2/3] test: address review feedback on sys/time tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove trivially-true Count >= 0 assertions; assert argv/path are non-empty instead - Drop redundant |> ignore no-ops - Remove sys.maxsize test — binding types it as int (Int32) but Python value overflows on 64-bit systems, so comparison returns False - Simplify time.sleep test to just call sleep (no-op assertion removed) Co-Authored-By: Claude Opus 4.7 (1M context) --- test/TestSys.fs | 14 ++++---------- test/TestTime.fs | 3 +-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/test/TestSys.fs b/test/TestSys.fs index 025aca6..5f4d8f4 100644 --- a/test/TestSys.fs +++ b/test/TestSys.fs @@ -11,23 +11,17 @@ let ``test sys.platform is non-empty string`` () = let ``test sys.version is non-empty string`` () = sys.version.Length > 0 |> equal true -[] -let ``test sys.maxsize is large positive int`` () = - sys.maxsize > 0 |> equal true - [] let ``test sys.maxunicode is 1114111`` () = sys.maxunicode |> equal 1114111 [] -let ``test sys.path is list`` () = - sys.path |> ignore - sys.path.Count >= 0 |> equal true +let ``test sys.path has at least one element`` () = + sys.path.Count > 0 |> equal true [] -let ``test sys.argv is list`` () = - sys.argv |> ignore - sys.argv.Count >= 0 |> equal true +let ``test sys.argv has at least one element`` () = + sys.argv.Count > 0 |> equal true [] let ``test sys.byteorder is little or big`` () = diff --git a/test/TestTime.fs b/test/TestTime.fs index ccf65ad..e1dba1a 100644 --- a/test/TestTime.fs +++ b/test/TestTime.fs @@ -41,8 +41,7 @@ let ``test time.ctime with seconds returns non-empty string`` () = [] let ``test time.sleep does not throw`` () = - time.sleep 0.0 |> ignore - true |> equal true + time.sleep 0.0 [] let ``test time.timezone is int`` () = From 7f4bc587ca21aa6e2e1731767fcb7268c8a197aa Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sat, 18 Apr 2026 06:49:02 +0200 Subject: [PATCH 3/3] fix(sys): type maxsize as nativeint instead of int MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Python's sys.maxsize is 2^63−1 on 64-bit systems, which overflows Fable's Int32 (the target type for F# int). nativeint maps to Python's native int, preserving the full value. Re-adds the maxsize positivity test. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/stdlib/Sys.fs | 2 +- test/TestSys.fs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/stdlib/Sys.fs b/src/stdlib/Sys.fs index fe84be6..209e68c 100644 --- a/src/stdlib/Sys.fs +++ b/src/stdlib/Sys.fs @@ -35,7 +35,7 @@ type IExports = /// Version information encoded as a single integer abstract hexversion: int /// Maximum value a variable of type int can take - abstract maxsize: int + abstract maxsize: nativeint /// Maximum Unicode code point value abstract maxunicode: int /// Module search path - list of directory names where Python looks for modules diff --git a/test/TestSys.fs b/test/TestSys.fs index 5f4d8f4..26b7530 100644 --- a/test/TestSys.fs +++ b/test/TestSys.fs @@ -11,6 +11,10 @@ let ``test sys.platform is non-empty string`` () = let ``test sys.version is non-empty string`` () = sys.version.Length > 0 |> equal true +[] +let ``test sys.maxsize is positive`` () = + sys.maxsize > 0n |> equal true + [] let ``test sys.maxunicode is 1114111`` () = sys.maxunicode |> equal 1114111