Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FSCS: Added tests for compilability of provided types #38

Merged
merged 7 commits into from
Jul 10, 2016
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
1 change: 1 addition & 0 deletions paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ group Test

source https://nuget.org/api/v2
nuget FSharp.Data
nuget FSharp.Compiler.Service

nuget NUnit
nuget NUnit.Console
Expand Down
57 changes: 29 additions & 28 deletions paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ NUGET
YamlDotNet (3.9)
GITHUB
remote: fsharp/FSharp.Data
src/CommonRuntime/IO.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/CommonRuntime/NameUtils.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/CommonRuntime/Pluralizer.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/CommonRuntime/StructuralTypes.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/CommonRuntime/TextConversions.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/Json/JsonConversions.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/Json/JsonExtensions.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/Json/JsonValue.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/Net/Http.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/Net/UriUtils.fs (e60322d4cf4a59cc30563b7b8974e09af544b7d7)
src/CommonRuntime/IO.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/CommonRuntime/NameUtils.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/CommonRuntime/Pluralizer.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/CommonRuntime/StructuralTypes.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/CommonRuntime/TextConversions.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/Json/JsonConversions.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/Json/JsonExtensions.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/Json/JsonValue.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/Net/Http.fs (45ca385efcb302929c4a66def596259fe61a095b)
src/Net/UriUtils.fs (45ca385efcb302929c4a66def596259fe61a095b)
remote: fsprojects/FSharp.TypeProviders.StarterPack
src/ProvidedTypes.fs (dfbca9b83fb70067e85abddcb8b89332aae4c28d)
src/ProvidedTypes.fsi (dfbca9b83fb70067e85abddcb8b89332aae4c28d)
Expand All @@ -36,8 +36,8 @@ NUGET
SourceLink.Fake (1.1)
GITHUB
remote: fsharp/FAKE
modules/Octokit/Octokit.fsx (c063bf415dac7f7d4df4c37fe76badce76cae3c3)
Octokit
modules/Octokit/Octokit.fsx (c56456abac6b744c3bb95b217687db19fd19b367)
Octokit (>= 0.20)
GROUP OWIN
FRAMEWORK: NET45
NUGET
Expand All @@ -61,7 +61,7 @@ NUGET
Microsoft.Owin.Hosting (3.0.1)
Microsoft.Owin (>= 3.0.1)
Owin (>= 1.0)
Newtonsoft.Json (8.0.3)
Newtonsoft.Json (9.0.1)
Owin (1.0)
Swashbuckle.Core (5.3.2)
Microsoft.AspNet.WebApi.Core (>= 4.0.20710)
Expand All @@ -70,21 +70,22 @@ GROUP Test
FRAMEWORK: NET45
NUGET
remote: https://www.nuget.org/api/v2
FSharp.Compiler.Service (5.0)
FSharp.Data (2.3.1)
NUnit (3.4)
NUnit.Console (3.4)
NUnit.ConsoleRunner (3.4)
NUnit.Extension.NUnitProjectLoader (3.4)
NUnit.Extension.NUnitV2Driver (3.4)
NUnit.Extension.NUnitV2ResultWriter (3.4)
NUnit.Extension.TeamCityEventListener (1.0)
NUnit.Extension.VSProjectLoader (3.4)
NUnit.ConsoleRunner (3.4)
NUnit.Extension.NUnitProjectLoader (3.4)
NUnit.Extension.NUnitV2Driver (3.4)
NUnit.Extension.NUnitV2ResultWriter (3.4)
NUnit.Extension.TeamCityEventListener (1.0)
NUnit.Extension.VSProjectLoader (3.4)
NUnit (3.4.1)
NUnit.Console (3.4.1)
NUnit.ConsoleRunner (>= 3.4.1)
NUnit.Extension.NUnitProjectLoader (>= 3.4.1)
NUnit.Extension.NUnitV2Driver (>= 3.4.1)
NUnit.Extension.NUnitV2ResultWriter (>= 3.4.1)
NUnit.Extension.TeamCityEventListener (>= 1.0.1)
NUnit.Extension.VSProjectLoader (>= 3.4.1)
NUnit.ConsoleRunner (3.4.1)
NUnit.Extension.NUnitProjectLoader (3.4.1)
NUnit.Extension.NUnitV2Driver (3.4.1)
NUnit.Extension.NUnitV2ResultWriter (3.4.1)
NUnit.Extension.TeamCityEventListener (1.0.1)
NUnit.Extension.VSProjectLoader (3.4.1)
GITHUB
remote: fsprojects/FsUnit
src/FsUnit.NUnit/FsUnitTyped.fs (a56aa15e019b044574b50b95ad14c8815a22716a)
src/FsUnit.NUnit/FsUnitTyped.fs (fdff2ee3af2478b79f094b0d065658d665aec83a)
8 changes: 4 additions & 4 deletions src/Common/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ open System.Reflection
[<assembly: AssemblyTitleAttribute("SwaggerProvider")>]
[<assembly: AssemblyProductAttribute("SwaggerProvider")>]
[<assembly: AssemblyDescriptionAttribute("F# Type Provider for Swagger")>]
[<assembly: AssemblyVersionAttribute("0.5.2")>]
[<assembly: AssemblyFileVersionAttribute("0.5.2")>]
[<assembly: AssemblyVersionAttribute("0.5.3")>]
[<assembly: AssemblyFileVersionAttribute("0.5.3")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] Version = "0.5.2"
let [<Literal>] InformationalVersion = "0.5.2"
let [<Literal>] Version = "0.5.3"
let [<Literal>] InformationalVersion = "0.5.3"
24 changes: 13 additions & 11 deletions src/SwaggerProvider.DesignTime/DefinitionCompiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

open ProviderImplementation.ProvidedTypes
open FSharp.Data.Runtime.NameUtils
open SwaggerProvider.Internal
open SwaggerProvider.Internal.Schema
open Microsoft.FSharp.Quotations
open System
Expand All @@ -21,16 +22,17 @@ type DefinitionCompiler (schema:SwaggerObject) =
providedTys.Add(newName, None)
newName

let generateProperty propName ty providedField =
let propertyName = nicePascalName propName
let property =
let generateProperty propName ty (scope:UniqueNameGenerator) =
let propertyName = scope.MakeUnique <| nicePascalName propName
let providedField = ProvidedField("_" + propertyName.ToLower(), ty)
let providedProperty =
ProvidedProperty(propertyName, ty,
GetterCode = (fun [this] -> Expr.FieldGet (this, providedField)),
SetterCode = (fun [this;v] -> Expr.FieldSet(this, providedField, v)))
if propName <> propertyName then
property.AddCustomAttribute
providedProperty.AddCustomAttribute
<| SwaggerProvider.Internal.RuntimeHelpers.getPropertyNameAttribute propName
property
providedField, providedProperty

let rec compileDefinition (tyDefName:string) =
match definitionTys.TryGetValue tyDefName with
Expand Down Expand Up @@ -82,18 +84,18 @@ type DefinitionCompiler (schema:SwaggerObject) =
else providedTys.Add(tyName, Some(ty))

ty.AddMember <| ProvidedConstructor([], InvokeCode = fun _ -> <@@ () @@>)
let propsNameScope = UniqueNameGenerator()
for p in properties do
if String.IsNullOrEmpty(p.Name)
then failwithf "Property cannot be created with empty name. Obj name:%A; ObjSchema:%A" tyName schemaObj

let pTy = compileSchemaObject (uniqueName tyName (nicePascalName p.Name)) p.Type p.IsRequired
let field = ProvidedField("_" + p.Name.ToLower(), pTy)
ty.AddMember <| field

let pPr = generateProperty p.Name pTy field
let (pField, pProp) = generateProperty p.Name pTy propsNameScope
if not <| String.IsNullOrWhiteSpace p.Description
then pPr.AddXmlDoc p.Description
ty.AddMember <| pPr
then pProp.AddXmlDoc p.Description

ty.AddMember <| pField
ty.AddMember <| pProp

ty :> Type
| Reference path, _ -> compileDefinition path
Expand Down
13 changes: 3 additions & 10 deletions src/SwaggerProvider.DesignTime/OperationCompiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

open ProviderImplementation.ProvidedTypes
open FSharp.Data.Runtime.NameUtils
open SwaggerProvider.Internal
open SwaggerProvider.Internal.Schema

open System
Expand Down Expand Up @@ -187,15 +188,7 @@ type OperationCompiler (schema:SwaggerObject, defCompiler:DefinitionCompiler) =

/// Compiles the operation.
member __.CompilePaths(ignoreOperationId) =
let methodNames = System.Collections.Generic.HashSet<_>()
let uniqueMethodName methodName =
let rec findUniq prefix i =
let newName = sprintf "%s%s" prefix (if i=0 then "" else i.ToString())
if not <| methodNames.Contains newName
then newName else findUniq prefix (i+1)
let newName = findUniq methodName 0
methodNames.Add newName |> ignore
newName
let methodNameScope = UniqueNameGenerator()
let pathToName opType (opPath:String) =
String.Join("_",
[|
Expand All @@ -213,4 +206,4 @@ type OperationCompiler (schema:SwaggerObject, defCompiler:DefinitionCompiler) =
List.ofArray schema.Paths
|> List.map (fun op ->
let methodNameCandidate = nicePascalName <| getMethodNameCandidate op
compileOperation (uniqueMethodName methodNameCandidate) op)
compileOperation (methodNameScope.MakeUnique methodNameCandidate) op)
4 changes: 2 additions & 2 deletions src/SwaggerProvider.DesignTime/SchemaParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ module Parser =
| true, lazeObj ->
match lazeObj.Value with
| Object props -> props
| _ -> failwithf "Could not compose %O" obj
| _ -> failwithf "Could not compose %A" obj
| _ -> failwithf "Reference to unknown type %s" path
| obj -> failwithf "Could not compose %O" obj)
| obj -> failwithf "Could not compose %A" obj)
|> Array.concat
Some <| Object props
| None -> None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
Expand Down Expand Up @@ -88,6 +88,7 @@
<Compile Include="..\Common\AssemblyInfo.fs">
<Link>AssemblyInfo.fs</Link>
</Compile>
<Compile Include="Utils.fs" />
<Compile Include="Schema.fs" />
<Compile Include="SchemaParserExceptions.fs" />
<Compile Include="SchemaNode.fs" />
Expand Down
17 changes: 17 additions & 0 deletions src/SwaggerProvider.DesignTime/Utils.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace SwaggerProvider.Internal

type UniqueNameGenerator() =
let hash = System.Collections.Generic.HashSet<_>()

let rec findUniq prefix i =
let newName = sprintf "%s%s" prefix (if i=0 then "" else i.ToString())
let key = newName.ToLowerInvariant()
match hash.Contains key with
| false ->
hash.Add key |> ignore
newName
| true ->
findUniq prefix (i+1)

member __.MakeUnique methodName =
findUniq methodName 0
2 changes: 1 addition & 1 deletion src/SwaggerProvider/SwaggerProvider.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
48 changes: 48 additions & 0 deletions tests/SwaggerProvider.ProviderTests/APIs.Guru.FSC.Tests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module APIsGuruFSCS

open Microsoft.FSharp.Compiler.SimpleSourceCodeServices
open System
open System.IO
open NUnit.Framework

let referencedAssemblies =
let rootDir = __SOURCE_DIRECTORY__ + "/../../bin/SwaggerProvider/"
["SwaggerProvider.Runtime.dll"
"SwaggerProvider.DesignTime.dll"
"SwaggerProvider.dll";]
|> List.map (fun x->
["-r"; Path.Combine(rootDir, x)])
|> List.concat

let scs = SimpleSourceCodeServices()


let toTestCase (url:string) =
TestCaseData(url).SetName(sprintf "Compile schema %s" url)
let JsonSchemasSource = APIsGuru.JsonSchemas |> Array.map toTestCase


[<Test; TestCaseSource("JsonSchemasSource")>]
let ``Compile TP`` url =
let tempFile = Path.GetTempFileName()
let fs = Path.ChangeExtension(tempFile, ".fs")
let dll = Path.ChangeExtension(tempFile, ".dll")

File.WriteAllText(fs, sprintf """
module TestModule
open SwaggerProvider
type ProvidedSwagger = SwaggerProvider<"%s">
let instance = ProvidedSwagger()
""" url)

let errors, exitCode =
scs.Compile(Array.ofList
(["fsc.exe"; "-o"; dll; "-a"; fs] @ referencedAssemblies))

[tempFile; fs; dll]
|> List.filter File.Exists
|> List.iter File.Delete

if exitCode <> 0 then
failwithf "Compilation error:\n%s"
(String.Join("\n", errors |> Array.map(fun x->x.ToString()) ))
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,17 @@
<Compile Include="Swashbuckle.ReturnControllers.Tests.fs" />
<Compile Include="Swashbuckle.UpdateControllers.Tests.fs" />
<Compile Include="Swashbuckle.ResourceControllers.Tests.fs" />
<Compile Include="..\SwaggerProvider.Tests\APIs.guru.fs">
<Link>APIs.guru.fs</Link>
</Compile>
<Compile Include="APIs.Guru.FSC.Tests.fs" />
<None Include="Script.fsx" />
<None Include="paket.references" />
<Content Include="App.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
<Private>False</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="SwaggerProvider">
Expand All @@ -112,6 +116,31 @@
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
</ItemGroup>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'">
<ItemGroup>
<Reference Include="FSharp.Compiler.Service">
<HintPath>..\..\packages\test\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'">
<ItemGroup>
<Reference Include="FSharp.Data">
<HintPath>..\..\packages\test\FSharp.Data\lib\net40\FSharp.Data.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
<Reference Include="System.Xml.Linq">
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'">
<ItemGroup>
Expand Down
2 changes: 2 additions & 0 deletions tests/SwaggerProvider.ProviderTests/paket.references
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
group Test
NUnit
FSharp.Data
FSharp.Compiler.Service
File:FsUnitTyped.fs
Loading