Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/stdlib/Builtins.fs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,30 @@ type IExports =
abstract int: obj -> int
/// Object to float
abstract float: obj -> float

/// Return the largest item in an iterable or the largest of two or more arguments.
abstract max: 'T * 'T -> 'T
/// Return the largest item in an iterable or the largest of two or more arguments.
abstract max: 'T * 'T * 'T -> 'T
/// Return the largest item in an iterable or the largest of two or more arguments.
abstract max: IEnumerable<'T> -> 'T

/// Return the smallest item in an iterable or the smallest of two or more arguments.
abstract min: 'T * 'T -> 'T
/// Return the smallest item in an iterable or the smallest of two or more arguments.
abstract min: 'T * 'T * 'T -> 'T
/// Return the smallest item in an iterable or the smallest of two or more arguments.
abstract min: IEnumerable<'T> -> 'T

/// Return the sum of a 'start' value (default: 0) plus an iterable of numbers.
abstract sum: IEnumerable<'T> -> 'T

/// Return True if bool(x) is True for all values x in the iterable.
abstract all: IEnumerable<bool> -> bool

/// Return True if bool(x) is True for any x in the iterable.
abstract any: IEnumerable<bool> -> bool

abstract print: obj: obj -> unit

[<NamedParams(fromIndex = 1)>]
Expand Down
12 changes: 12 additions & 0 deletions src/stdlib/Os.fs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ and [<Erase>] PathModule =
/// Return the base name of pathname path
/// See https://docs.python.org/3/library/os.path.html#os.path.basename
abstract basename: path: string -> string
/// Return the argument with an initial component of ~ or ~user replaced
/// See https://docs.python.org/3/library/os.path.html#os.path.expanduser
abstract expanduser: path: string -> string
/// Return a normalized absolutized version of the pathname path
/// See https://docs.python.org/3/library/os.path.html#os.path.abspath
abstract abspath: path: string -> string
/// Split the pathname path into a pair (head, tail)
/// See https://docs.python.org/3/library/os.path.html#os.path.split
abstract split: path: string -> string * string
/// Split the pathname path into a pair (root, ext)
/// See https://docs.python.org/3/library/os.path.html#os.path.splitext
abstract splitext: path: string -> string * string


/// Miscellaneous operating system interfaces
Expand Down
1 change: 1 addition & 0 deletions test/Fable.Python.Test.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<Compile Include="TestAst.fs" />
<Compile Include="TestAsyncIO.fs" />
<Compile Include="TestBuiltins.fs" />
<Compile Include="TestOs.fs" />
<Compile Include="TestJson.fs" />
<Compile Include="TestString.fs" />
<Compile Include="Main.fs" />
Expand Down
53 changes: 52 additions & 1 deletion test/TestBuiltins.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Fable.Python.Tests.Builtins

open Util.Testing
open Fable.Python.Builtins
open Fable.Python.Os

[<Fact>]
let ``test print works`` () =
Expand All @@ -12,5 +13,55 @@ let ``test __name__ works`` () = __name__ |> equal "test_builtins"

[<Fact>]
let ``test write works`` () =
let result = builtins.``open``("test.txt", OpenTextMode.Write)
let tempFile = os.path.join (os.path.expanduser "~", ".fable_test_temp.txt")
let result = builtins.``open``(tempFile, OpenTextMode.Write)
result.write "ABC" |> equal 3
result.Dispose()
os.remove tempFile

[<Fact>]
let ``test max with two arguments works`` () =
builtins.max (3, 5) |> equal 5
builtins.max (10, 2) |> equal 10

[<Fact>]
let ``test max with three arguments works`` () =
builtins.max (3, 5, 1) |> equal 5
builtins.max (1, 2, 10) |> equal 10

[<Fact>]
let ``test max with iterable works`` () =
builtins.max [1; 2; 3; 4; 5] |> equal 5
builtins.max [10; -5; 3] |> equal 10

[<Fact>]
let ``test min with two arguments works`` () =
builtins.min (3, 5) |> equal 3
builtins.min (10, 2) |> equal 2

[<Fact>]
let ``test min with three arguments works`` () =
builtins.min (3, 5, 1) |> equal 1
builtins.min (1, 2, 10) |> equal 1

[<Fact>]
let ``test min with iterable works`` () =
builtins.min [1; 2; 3; 4; 5] |> equal 1
builtins.min [10; -5; 3] |> equal -5

[<Fact>]
let ``test sum works`` () =
builtins.sum [1; 2; 3; 4; 5] |> equal 15
builtins.sum [10; -5; 3] |> equal 8

[<Fact>]
let ``test all works`` () =
builtins.all [true; true; true] |> equal true
builtins.all [true; false; true] |> equal false
builtins.all [] |> equal true

[<Fact>]
let ``test any works`` () =
builtins.any [false; false; true] |> equal true
builtins.any [false; false; false] |> equal false
builtins.any [] |> equal false
30 changes: 30 additions & 0 deletions test/TestJson.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,33 @@ let ``test json loads works`` () =
let object = {| Foo = 10; Bar = "test" |}
let result: {| Foo: int; Bar: string |} = unbox (json.loads input)
result |> equal object

[<Fact>]
let ``test json.dumps with nativeint works`` () =
let value: nativeint = 42n
let result = json.dumps value
result |> equal "42"

[<Fact>]
let ``test json.dumps with ResizeArray of nativeint works`` () =
let values = ResizeArray([1n; 2n; 3n])
let result = json.dumps values
result |> equal "[1, 2, 3]"

[<Fact>]
let ``test json.dumps with nested object works`` () =
let obj = {| Name = "test"; Values = ResizeArray([1n; 2n; 3n]) |}
let result = dumps obj
result |> equal """{"Name": "test", "Values": [1, 2, 3]}"""

[<Fact>]
let ``test json.loads with array works`` () =
let input = "[1, 2, 3]"
let result: int array = unbox (json.loads input)
result.Length |> equal 3

[<Fact>]
let ``test json.dumps with indent works`` () =
let obj = {| A = 1n |}
let result = dumpsIndented obj 2
result.Contains("\n") |> equal true
61 changes: 61 additions & 0 deletions test/TestOs.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module Fable.Python.Tests.Os

open Util.Testing
open Fable.Python.Os

[<Fact>]
let ``test os.path.exists works`` () =
os.path.exists "." |> equal true
os.path.exists "nonexistent_path_xyz" |> equal false

[<Fact>]
let ``test os.path.isdir works`` () =
os.path.isdir "." |> equal true

[<Fact>]
let ``test os.path.join works`` () =
os.path.join ("a", "b", "c") |> equal "a/b/c"

[<Fact>]
let ``test os.path.dirname works`` () =
os.path.dirname "/foo/bar/baz.txt" |> equal "/foo/bar"

[<Fact>]
let ``test os.path.basename works`` () =
os.path.basename "/foo/bar/baz.txt" |> equal "baz.txt"

[<Fact>]
let ``test os.path.expanduser works`` () =
let expanded = os.path.expanduser "~"
// The expanded path should not start with ~ anymore
expanded.StartsWith("~") |> equal false

[<Fact>]
let ``test os.path.abspath works`` () =
let absPath = os.path.abspath "."
// Absolute path should start with /
absPath.StartsWith("/") |> equal true

[<Fact>]
let ``test os.path.split works`` () =
let head, tail = os.path.split "/foo/bar/baz.txt"
head |> equal "/foo/bar"
tail |> equal "baz.txt"

[<Fact>]
let ``test os.path.splitext works`` () =
let root, ext = os.path.splitext "/foo/bar/baz.txt"
root |> equal "/foo/bar/baz"
ext |> equal ".txt"

[<Fact>]
let ``test os.getcwd works`` () =
let cwd = os.getcwd ()
// Current working directory should be a non-empty string
cwd.Length > 0 |> equal true

[<Fact>]
let ``test os.listdir works`` () =
let entries = os.listdir "."
// Current directory should have at least some entries
entries.Length > 0 |> equal true