Skip to content

Commit

Permalink
Add test
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsogarciacaro committed Oct 1, 2021
1 parent e863f6b commit 4362b08
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 41 deletions.
5 changes: 3 additions & 2 deletions src/Fable.Core/Fable.Core.Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ type ParamListAttribute() =

type ParamSeqAttribute = ParamListAttribute

/// Used to convert arguments from specified index into an object
/// Converts arguments from the specified index on (0 by default) into an object.
/// IMPORTANT: This should be used only with native bindings.
[<AttributeUsage(AttributeTargets.Constructor ||| AttributeTargets.Method)>]
type ParamObjectAttribute(int: int) =
type ParamObjectAttribute(fromIndex: int) =
inherit Attribute()
new () = ParamObjectAttribute(0)

Expand Down
61 changes: 31 additions & 30 deletions src/Fable.Transforms/Fable2Babel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1115,9 +1115,9 @@ module Util =
let objKeys = List.take (List.length objValues) objKeys
let objArg =
List.zip objKeys objValues
|> List.filter (function
| _, Fable.Value(Fable.NewOption(None,_),_) -> false
| _ -> true)
|> List.choose (function
| k, Fable.Value(Fable.NewOption(value,_),_) -> value |> Option.map (fun v -> k, v)
| k, v -> Some(k, v))
|> List.map (fun (k, v) -> k, com.TransformAsExpr(ctx, v))
|> makeJsObject
args, Some objArg
Expand Down Expand Up @@ -1175,33 +1175,34 @@ module Util =
// Check only members with multiple non-curried arguments
| [parameters], Some ent when not (List.isEmpty parameters) ->
let ent = com.GetEntity(ent)
ent.MembersFunctionsAndValues
|> Seq.tryFind (fun m ->
m.IsInstance = memberInfo.IsInstance
&& m.CompiledName = memberInfo.CompiledName
&& match m.CurriedParameterGroups with
| [parameters2] when List.sameLength parameters parameters2 ->
List.zip parameters parameters2 |> List.forall (fun (p1, p2) -> typeEquals true p1.Type p2.Type)
| _ -> false)
|> Option.bind (fun m ->
m.Attributes |> Seq.tryPick (fun a ->
if a.Entity.FullName = Atts.paramObject then
let index =
match a.ConstructorArgs with
| (:? int as index)::_ -> index
| _ -> 0
match tryGetParamNames parameters with
| None ->
"ParamObj cannot be used with unnamed parameters"
|> addWarning com [] range
None
| Some paramNames ->
Some { Index = index
Parameters = paramNames }
else None
)
)
| _ -> None
if ent.IsInterface || FSharp2Fable.Util.isGlobalOrImportedEntity ent then
ent.MembersFunctionsAndValues
|> Seq.tryFind (fun m ->
m.IsInstance = memberInfo.IsInstance
&& m.CompiledName = memberInfo.CompiledName
&& match m.CurriedParameterGroups with
| [parameters2] when List.sameLength parameters parameters2 ->
List.zip parameters parameters2 |> List.forall (fun (p1, p2) -> typeEquals true p1.Type p2.Type)
| _ -> false)
|> Option.bind (fun m ->
m.Attributes |> Seq.tryPick (fun a ->
if a.Entity.FullName = Atts.paramObject then
let index =
match a.ConstructorArgs with
| (:? int as index)::_ -> index
| _ -> 0
match tryGetParamNames parameters with
| None ->
"ParamObj cannot be used with unnamed parameters"
|> addWarning com [] range
None
| Some paramNames ->
Some { Index = index
Parameters = paramNames }
else None
))
else None
| _ -> None

let transformEmit (com: IBabelCompiler) ctx range (info: Fable.EmitInfo) =
let macro = info.Macro
Expand Down
9 changes: 0 additions & 9 deletions src/quicktest/QuickTest.fs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,3 @@ let measureTime (f: unit -> unit) = emitJsStatement () """
// to Fable.Tests project. For example:
// testCase "Addition works" <| fun () ->
// 2 + 2 |> equal 4

[<Global>]
type MyJsClass [<ParamObject>] (?foo: int, ?bar: string, ?baz: float) =
[<ParamObject(2)>]
member _.Foo(foo: int, bar: string, ?baz: float) = jsNative

let test() =
let c = MyJsClass(4, baz=56.)
c.Foo(5, baz=4., bar="b")
17 changes: 17 additions & 0 deletions tests/Main/ImportTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ type MyClass() =
static member foo(): string = jsNative
static member foo(i: int): int = jsNative

[<ImportMember("./js/1foo.js")>]
type MyJsClassWithOptionArgs
[<ParamObject>]
(?foo: int, ?bar: string, ?baz: float) =
[<ParamObject(2)>]
member _.method(foo: int, bar: string, baz: float, ?lol: int) = jsNative
member _.value: string = jsNative

type FooOptional =
abstract Foo1: x: int * ?y: string -> int
abstract Foo2: x: int * y: string option -> int
Expand Down Expand Up @@ -99,6 +107,15 @@ let tests =

testCase "Static members of imported classes work" <| fun () ->
MyJsClass.fuzzyMultiply(5, 4) |> equal 15

testCase "ParamObject works with constructors" <| fun () ->
let c = MyJsClassWithOptionArgs(4, baz=5.6)
c.value |> equal "4undefined5.6"

testCase "ParamObject works with fromIndex arg" <| fun () ->
let c = MyJsClassWithOptionArgs()
c.method(5, baz=4., lol=10, bar="b")
|> equal "5b410"
#endif

testCase "Import with relative paths from project subdirectory works" <| fun () ->
Expand Down
9 changes: 9 additions & 0 deletions tests/Main/js/1foo.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,12 @@ export function handleClass(constructor) {
x.Times = 2;
return x.SaySomethingTo("Narumi");
}

export class MyJsClassWithOptionArgs {
constructor(opts) {
this.value = String(opts.foo) + String(opts.bar) + String(opts.baz);
}
method(foo, bar, opts) {
return String(foo) + String(bar) + String(opts.baz) + String(opts.lol);
}
}

0 comments on commit 4362b08

Please sign in to comment.