forked from dotnet/fsharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TypeProviderTests.fs
391 lines (252 loc) · 12.8 KB
/
TypeProviderTests.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
#if INTERACTIVE
//#r @"../../release/net40/bin/FSharp.Compiler.dll"
#r @"../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#load "../../src/scripts/scriptlib.fsx"
#load "../FSharp.Test.Utilities/TestFramework.fs"
#load "single-test.fs"
#else
[<NUnit.Framework.Category "Type Provider";NUnit.Framework.NonParallelizable>]
module FSharp.Test.FSharpSuite.TypeProviderTests
#endif
open System
open System.IO
open System.Reflection
open NUnit.Framework
open TestFramework
open Scripting
open SingleTest
open FSharp.Compiler.IO
#if !NETCOREAPP
// All tests which do a manual invoke of the F# compiler are disabled
#if NETCOREAPP
// Use these lines if you want to test CoreCLR
let FSC_OPTIMIZED = FSC_NETCORE (true, false)
let FSI = FSI_NETCORE
#else
let FSC_OPTIMIZED = FSC_NETFX (true, false)
let FSI = FSI_NETFX
#endif
let inline getTestsDirectory dir = getTestsDirectory __SOURCE_DIRECTORY__ dir
let testConfig = getTestsDirectory >> testConfig
[<Test>]
let diamondAssembly () =
let cfg = testConfig "typeProviders/diamondAssembly"
rm cfg "provider.dll"
// Add a version flag to make this generate native resources. The native resources aren't important and
// can be dropped when the provided.dll is linked but we need to tolerate generated DLLs that have them
fsc cfg "%s" "--out:provided.dll -a --version:0.0.0.1" [".." ++ "helloWorld" ++ "provided.fs"]
fsc cfg "%s" "--out:provider.dll -a" [".." ++ "helloWorld" ++ "provider.fsx"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test1.dll -a" cfg.fsc_flags ["test1.fsx"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2a.dll -a -r:test1.dll" cfg.fsc_flags ["test2a.fsx"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2b.dll -a -r:test1.dll" cfg.fsc_flags ["test2b.fsx"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test3.exe -r:test1.dll -r:test2a.dll -r:test2b.dll" cfg.fsc_flags ["test3.fsx"]
peverify cfg "test1.dll"
peverify cfg "test2a.dll"
peverify cfg "test2b.dll"
peverify cfg "test3.exe"
exec cfg ("." ++ "test3.exe") ""
use testOkFile = fileguard cfg "test.ok"
fsi cfg "%s" cfg.fsi_flags ["test3.fsx"]
testOkFile.CheckExists()
[<Test>]
let globalNamespace () =
let cfg = testConfig "typeProviders/globalNamespace"
csc cfg """/out:globalNamespaceTP.dll /debug+ /target:library /r:netstandard.dll /r:"%s" """ cfg.FSCOREDLLPATH ["globalNamespaceTP.cs"]
fsc cfg "%s /debug+ /r:globalNamespaceTP.dll /optimize-" cfg.fsc_flags ["test.fsx"]
let helloWorld p =
let cfg = testConfig "typeProviders/helloWorld"
fsc cfg "%s" "--out:provided1.dll -g -a" [".." ++ "helloWorld" ++ "provided.fs"]
fsc cfg "%s" "--out:provided2.dll -g -a" [".." ++ "helloWorld" ++ "provided.fs"]
fsc cfg "%s" "--out:provided3.dll -g -a" [".." ++ "helloWorld" ++ "provided.fs"]
fsc cfg "%s" "--out:provided4.dll -g -a" [".." ++ "helloWorld" ++ "provided.fs"]
fsc cfg "%s" "--out:providedJ.dll -g -a" [".." ++ "helloWorld" ++ "providedJ.fs"]
fsc cfg "%s" "--out:providedK.dll -g -a" [".." ++ "helloWorld" ++ "providedK.fs"]
fsc cfg "%s" "--out:providedNullAssemblyName.dll -g -a" [".." ++ "helloWorld" ++ "providedNullAssemblyName.fsx"]
fsc cfg "--out:provided.dll -a" [".." ++ "helloWorld" ++ "provided.fs"]
fsc cfg "--out:providedJ.dll -a" [".." ++ "helloWorld" ++ "providedJ.fs"]
fsc cfg "--out:providedK.dll -a" [".." ++ "helloWorld" ++ "providedK.fs"]
fsc cfg "--out:provider.dll -a" ["provider.fsx"]
SingleTest.singleTestBuildAndRunAux cfg p
rm cfg "provider_with_binary_compat_changes.dll"
mkdir cfg "bincompat1"
log "pushd bincompat1"
let bincompat1 = getfullpath cfg "bincompat1"
Directory.EnumerateFiles(bincompat1 ++ "..", "*.dll")
|> Seq.iter (fun from -> Commands.copy bincompat1 from ("." ++ Path.GetFileName(from)) |> ignore)
fscIn cfg bincompat1 "%s" "-g -a -o:test_lib.dll -r:provider.dll" [".." ++ "test.fsx"]
fscIn cfg bincompat1 "%s" "-r:test_lib.dll -r:provider.dll" [".." ++ "testlib_client.fsx"]
log "popd"
mkdir cfg "bincompat2"
log "pushd bincompat2"
let bincompat2 = getfullpath cfg "bincompat2"
for fromFile in Directory.EnumerateFiles(bincompat2 ++ ".." ++ "bincompat1", "*.dll") do
Commands.copy bincompat2 fromFile ("." ++ Path.GetFileName(fromFile)) |> ignore
fscIn cfg bincompat2 "%s" "--define:ADD_AN_OPTIONAL_STATIC_PARAMETER --define:USE_IMPLICIT_ITypeProvider2 --out:provider.dll -g -a" [".." ++ "provider.fsx"]
fscIn cfg bincompat2 "-g -a -o:test_lib_recompiled.dll -r:provider.dll" [".." ++ "test.fsx"]
fscIn cfg bincompat2 "%s" "--define:ADD_AN_OPTIONAL_STATIC_PARAMETER -r:test_lib.dll -r:provider.dll" [".." ++ "testlib_client.fsx"]
peverify cfg (bincompat2 ++ "provider.dll")
peverify cfg (bincompat2 ++ "test_lib.dll")
peverify cfg (bincompat2 ++ "test_lib_recompiled.dll")
peverify cfg (bincompat2 ++ "testlib_client.exe")
[<Test>]
let ``helloWorld fsc`` () = helloWorld FSC_OPTIMIZED
#if !NETCOREAPP
[<Test>]
let ``helloWorld fsi`` () = helloWorld FSI_NETFX_STDIN
#endif
[<Test>]
let helloWorldCSharp () =
let cfg = testConfig "typeProviders/helloWorldCSharp"
rm cfg "magic.dll"
fsc cfg "%s" "--out:magic.dll -a --keyfile:magic.snk" ["magic.fs "]
rm cfg "provider.dll"
csc cfg """/out:provider.dll /target:library "/r:%s" /r:netstandard.dll /r:magic.dll""" cfg.FSCOREDLLPATH ["provider.cs"]
fsc cfg "%s /debug+ /r:provider.dll /optimize-" cfg.fsc_flags ["test.fsx"]
peverify cfg "magic.dll"
peverify cfg "provider.dll"
peverify cfg "test.exe"
exec cfg ("." ++ "test.exe") ""
[<TestCase("neg1")>]
[<TestCase("neg2")>]
[<TestCase("neg2c")>]
[<TestCase("neg2e")>]
[<TestCase("neg2g")>]
[<TestCase("neg2h")>]
[<TestCase("neg4")>]
[<TestCase("neg6")>]
[<TestCase("InvalidInvokerExpression")>]
[<TestCase("providerAttributeErrorConsume")>]
[<TestCase("ProviderAttribute_EmptyConsume")>]
[<TestCase("EVIL_PROVIDER_GetNestedNamespaces_Exception")>]
[<TestCase("EVIL_PROVIDER_NamespaceName_Exception")>]
[<TestCase("EVIL_PROVIDER_NamespaceName_Empty")>]
[<TestCase("EVIL_PROVIDER_GetTypes_Exception")>]
[<TestCase("EVIL_PROVIDER_ResolveTypeName_Exception")>]
[<TestCase("EVIL_PROVIDER_GetNamespaces_Exception")>]
[<TestCase("EVIL_PROVIDER_GetStaticParameters_Exception")>]
[<TestCase("EVIL_PROVIDER_GetInvokerExpression_Exception")>]
[<TestCase("EVIL_PROVIDER_GetTypes_Null")>]
[<TestCase("EVIL_PROVIDER_ResolveTypeName_Null")>]
[<TestCase("EVIL_PROVIDER_GetNamespaces_Null")>]
[<TestCase("EVIL_PROVIDER_GetStaticParameters_Null")>]
[<TestCase("EVIL_PROVIDER_GetInvokerExpression_Null")>]
[<TestCase("EVIL_PROVIDER_DoesNotHaveConstructor")>]
[<TestCase("EVIL_PROVIDER_ConstructorThrows")>]
[<TestCase("EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments")>]
[<NonParallelizable>]
let ``negative type provider tests`` (name:string) =
let cfg = testConfig "typeProviders/negTests"
let dir = cfg.Directory
if requireENCulture () then
let fileExists = Commands.fileExists dir >> Option.isSome
rm cfg "provided.dll"
fsc cfg "--out:provided.dll -a" [".." ++ "helloWorld" ++ "provided.fs"]
rm cfg "providedJ.dll"
fsc cfg "--out:providedJ.dll -a" [".." ++ "helloWorld" ++ "providedJ.fs"]
rm cfg "providedK.dll"
fsc cfg "--out:providedK.dll -a" [".." ++ "helloWorld" ++ "providedK.fs"]
rm cfg "provider.dll"
fsc cfg "--out:provider.dll -g --optimize- -a" ["provider.fsx"]
fsc cfg "--out:provider_providerAttributeErrorConsume.dll -a" ["providerAttributeError.fsx"]
fsc cfg "--out:provider_ProviderAttribute_EmptyConsume.dll -a" ["providerAttribute_Empty.fsx"]
rm cfg "helloWorldProvider.dll"
fsc cfg "--out:helloWorldProvider.dll -g --optimize- -a" [".." ++ "helloWorld" ++ "provider.fsx"]
rm cfg "MostBasicProvider.dll"
fsc cfg "--out:MostBasicProvider.dll -g --optimize- -a" ["MostBasicProvider.fsx"]
let preprocess name pref =
let dirp = (dir |> Commands.pathAddBackslash)
do
FileSystem.OpenFileForReadShim(sprintf "%s%s.%sbslpp" dirp name pref)
.ReadAllText()
.Replace("<ASSEMBLY>", getfullpath cfg (sprintf "provider_%s.dll" name))
.Replace("<FILEPATH>",dirp)
.Replace("<URIPATH>",sprintf "file:///%s" dirp)
|> fun txt -> FileSystem.OpenFileForWriteShim(sprintf "%s%s.%sbsl" dirp name pref).Write(txt)
if name = "ProviderAttribute_EmptyConsume" || name = "providerAttributeErrorConsume" then ()
else fsc cfg "--define:%s --out:provider_%s.dll -a" name name ["provider.fsx"]
if fileExists (sprintf "%s.bslpp" name) then preprocess name ""
if fileExists (sprintf "%s.vsbslpp" name) then preprocess name "vs"
SingleTest.singleNegTest cfg name
let splitAssembly subdir project =
let subdir = getTestsDirectory subdir
let cfg = testConfig project
let clean() =
rm cfg "providerDesigner.dll"
rmdir cfg "typeproviders"
rmdir cfg "tools"
rmdir cfg (".." ++ "typeproviders")
rmdir cfg (".." ++ "tools")
clean()
fsc cfg "--out:provider.dll -a" ["provider.fs"]
fsc cfg "--out:providerDesigner.dll -a" ["providerDesigner.fsx"]
fsc cfg "--out:test.exe -r:provider.dll" ["test.fsx"]
begin
use testOkFile = fileguard cfg "test.ok"
exec cfg ("." ++ "test.exe") ""
testOkFile.CheckExists()
end
begin
use testOkFile = fileguard cfg "test.ok"
fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
testOkFile.CheckExists()
end
// Do the same thing with different load locations for the type provider design-time component
clean()
// check a few load locations
let someLoadPaths =
[ subdir ++ "fsharp41" ++ "net48"
subdir ++ "fsharp41" ++ "net472"
subdir ++ "fsharp41" ++ "net461"
subdir ++ "fsharp41" ++ "net45"
// include up one directory
".." ++ subdir ++ "fsharp41" ++ "net45"
subdir ++ "fsharp41" ++ "netstandard2.0" ]
for dir in someLoadPaths do
printfn ""
printfn "Checking load path '%s'" dir
clean()
// put providerDesigner.dll into a different place
mkdir cfg dir
fsc cfg "--out:%s/providerDesigner.dll -a" dir ["providerDesigner.fsx"]
fsc cfg "--out:test.exe -r:provider.dll" ["test.fsx"]
begin
use testOkFile = fileguard cfg "test.ok"
exec cfg ("." ++ "test.exe") ""
testOkFile.CheckExists()
end
begin
use testOkFile = fileguard cfg "test.ok"
fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
testOkFile.CheckExists()
end
clean()
[<Test>]
let splitAssemblyTools () = splitAssembly "tools" "typeProviders/splitAssemblyTools"
[<Test>]
let splitAssemblyTypeProviders () = splitAssembly "typeproviders" "typeProviders/splitAssemblyTypeproviders"
[<Test>]
let wedgeAssembly () =
let cfg = testConfig "typeProviders/wedgeAssembly"
rm cfg "provider.dll"
rm cfg "provided.dll"
fsc cfg "%s" "--out:provided.dll -a" [".." ++ "helloWorld" ++ "provided.fs"]
rm cfg "providedJ.dll"
fsc cfg "%s" "--out:providedJ.dll -a" [".." ++ "helloWorld" ++ "providedJ.fs"]
rm cfg "providedK.dll"
fsc cfg "%s" "--out:providedK.dll -a" [".." ++ "helloWorld" ++ "providedK.fs"]
fsc cfg "%s" "--out:provider.dll -a" [".." ++ "helloWorld" ++ "provider.fsx"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2a.dll -a" cfg.fsc_flags ["test2a.fs"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2b.dll -a" cfg.fsc_flags ["test2b.fs"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test3.exe" cfg.fsc_flags ["test3.fsx"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2a-with-sig.dll -a" cfg.fsc_flags ["test2a.fsi"; "test2a.fs"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2b-with-sig.dll -a" cfg.fsc_flags ["test2b.fsi"; "test2b.fs"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test3-with-sig.exe --define:SIGS" cfg.fsc_flags ["test3.fsx"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2a-with-sig-restricted.dll -a" cfg.fsc_flags ["test2a-restricted.fsi"; "test2a.fs"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test2b-with-sig-restricted.dll -a"cfg.fsc_flags ["test2b-restricted.fsi"; "test2b.fs"]
fsc cfg "%s --debug+ -r:provider.dll --optimize- -o:test3-with-sig-restricted.exe --define:SIGS_RESTRICTED" cfg.fsc_flags ["test3.fsx"]
peverify cfg "test2a.dll"
peverify cfg "test2b.dll"
peverify cfg "test3.exe"
exec cfg ("." ++ "test3.exe") ""
#endif