/FingTest/TypeTests.fs

http://github.com/sandersn/fing · F# · 195 lines · 180 code · 3 blank · 12 comment · 6 complexity · 8705f75bb6671da6067c3a8c6de02819 MD5 · raw file

  1. module Fing.TypeTests
  2. open NUnit.Framework
  3. open Microsoft.FSharp.Metadata
  4. open Util
  5. open Types
  6. open TestCases
  7. open TestUtil
  8. [<TestFixture>]
  9. type public TypeTester() =
  10. let foldTypar empty singleton concat =
  11. let rec fold = function
  12. | Var v -> singleton v
  13. | Arrow types -> concat (List.map fold types)
  14. | Tuple types -> concat (List.map fold types)
  15. | Id _ -> empty
  16. | NamedArg(_,t,_) -> fold t
  17. | Generic (t,types) ->
  18. concat (fold t :: List.map fold types)
  19. | Array(_,t) -> fold t
  20. | Constraint(when_,t) ->
  21. concat [fold t; foldWhen when_]
  22. and foldWhen = function
  23. | Null v -> singleton v
  24. | Struct v -> singleton v
  25. | NotStruct v -> singleton v
  26. | DefaultConstructor v -> singleton v
  27. | Enum(v, t) -> concat [singleton v; fold t]
  28. | Delegate(v, t, t') -> concat [singleton v; fold t; fold t']
  29. | Subtype(v, t) -> concat [singleton v; fold t]
  30. | Sig(v, t, t', p) -> concat [singleton v; fold t; fold t']
  31. | TyparConstraint cons -> concat (List.map foldWhen cons)
  32. fold
  33. let usedVars = foldTypar [] (fun x -> [x]) List.concat
  34. let usedIndices = foldTypar Set.empty Set.singleton Set.unionMany
  35. [<Test>]
  36. member this.TestFormat() =
  37. safezip (List.map Parser.parse passes)
  38. (List.map (Types.format >> Parser.parse) passresults )
  39. |> testall
  40. [<Test>]
  41. member this.TestIndex() =
  42. let randomise seq = Seq.zip seq (seq |> Array.ofSeq |> Array.shuffle)
  43. let subst (t, shuffles) =
  44. let map = Map.ofSeq shuffles
  45. let subst' = function
  46. | Var v -> Some (Var (Map.find v map))
  47. | _ -> None
  48. Types.mapSimple subst' t
  49. let testPropEq f g = safezip (List.map f passresults) (List.map g passresults) |> testall
  50. // 1. length (usedIndices t) == length (usedIndices (index t))
  51. testPropEq (usedIndices >> Set.count)
  52. (Types.index >> usedIndices >> Set.count)
  53. // 2. length (set (leftToRightListOfVariableNames (index t))) == length (usedIndices (index t))
  54. testPropEq (Types.index >> usedVars >> set >> Set.count)
  55. (Types.index >> usedIndices >> Set.count)
  56. [<Test>]
  57. member this.TestRevMap() =
  58. testWith Types.revMap [
  59. Map.empty, Map.empty
  60. Map.ofList [("a","b")], Map.ofList [("b","a")]
  61. Map.ofList [("a","b");("a","c")], Map.ofList [("c", "a")]
  62. ]
  63. member this.TestMapTypar() =
  64. ()
  65. [<Test>]
  66. member this.TestMapSimple() =
  67. // 1. id == mapSimple Some
  68. forallt (fun t -> (t, Types.mapSimple Some t))
  69. // 2. id == mapSimple None
  70. forallt (fun t -> (t, Types.mapSimple (constant None) t))
  71. [<Test>]
  72. member this.TestMap() =
  73. // 1. id == map Some Some
  74. forallt (fun t -> (t, Types.map (fun _ _ t -> Some t) (fun _ _ w -> Some w) t))
  75. // 2. id == map None None
  76. forallt (fun t -> (t, Types.map (fun _ _ _ -> None) (fun _ _ _ -> None) t))
  77. // 3. replacing all vars with anonymous via map means that usedVars t == { Anonymous }
  78. let anonymiser _ _ = function
  79. | Var _ -> Some (Var Anonymous)
  80. | _ -> None
  81. let anonymiserW kt kw = function
  82. | Null _ -> Some (Null Anonymous)
  83. | Struct _ -> Some (Struct Anonymous)
  84. | NotStruct _ -> Some (NotStruct Anonymous)
  85. | DefaultConstructor _ -> Some (DefaultConstructor Anonymous)
  86. | Enum(_,t) -> Some (Enum(Anonymous, kt t))
  87. | Delegate(_,t,t') -> Some(Delegate(Anonymous, kt t, kt t'))
  88. | Subtype (_,t) -> Some(Subtype(Anonymous, kt t))
  89. | Sig(_,t,t',prop) -> Some(Sig(Anonymous, kt t, kt t', prop))
  90. | _ -> None
  91. forallt (fun t ->
  92. match Types.map anonymiser anonymiserW t |> usedVars with
  93. | [] -> (Set.empty, Set.empty)
  94. | vs -> (Set.singleton Anonymous, set vs))
  95. [<Test>]
  96. member this.TestUsedIds() =
  97. // this is a DSL because I used Sun-style indentation for my square brackets
  98. // and I passed a function. It's the future!
  99. testWith Types.usedIds [
  100. Set.empty, Var Anonymous
  101. Set.empty, Var (Normal "a")
  102. Set.singleton "int", Id "int"
  103. Set.singleton "int", Arrow [Id "int"; Id "int"]
  104. Set.ofList ["int"; "double"], Arrow [Id "int"; Id "double"]
  105. Set.ofList ["int"; "double"], Arrow [Id "int"; Var Anonymous; Id "double"]
  106. ]
  107. [<TestFixture>]
  108. type public FSharpTypeTester() =
  109. let core = FSharpAssembly.FSharpLibrary
  110. let rawts = seq {
  111. for e in core.Entities do
  112. for m in e.MembersOrValues do
  113. yield m
  114. }
  115. [<Test>]
  116. member this.TestDebinarise() =
  117. let tests = [
  118. Arrow [Id "int"], Arrow [Id "int"]
  119. Arrow [Id "int"; Id "int"], Arrow [Id "int"; Id "int"]
  120. Arrow [Id "int"; Id "int"; Id "int"], Arrow [Id "int"; Arrow [Id "int"; Id "int"]]
  121. // right branching only
  122. Arrow [Arrow [Id "int"; Id "int"]; Id "int"], Arrow [Arrow [Id "int"; Id "int"]; Id "int"]
  123. Var Anonymous, Var Anonymous
  124. Constraint
  125. (Sig
  126. (Choice [Normal "a"; Normal "b"],Id "read",
  127. Arrow [Id "string"; Id "int"; Id "stream"],Function),
  128. Generic (Id "list",[Var (Normal "a")])),
  129. Constraint
  130. (Sig
  131. (Choice [Normal "a"; Normal "b"],Id "read",
  132. Arrow [Id "string"; Arrow [Id "int"; Id "stream"]],Function),
  133. Generic (Id "list",[Var (Normal "a")]))
  134. Constraint
  135. (Sig
  136. (Normal "a",Generic (Id "read",[Var (Normal "b"); Var (Normal "c")]),
  137. Arrow [Var (Normal "a"); Var (Normal "b"); Var (Normal "c")],Function),
  138. Generic (Id "list",[Var (Normal "a")])),
  139. Constraint
  140. (Sig
  141. (Normal "a",Generic (Id "read",[Var (Normal "b"); Var (Normal "c")]),
  142. Arrow [Var (Normal "a"); Var (Normal "b"); Var (Normal "c")],Function),
  143. Generic (Id "list",[Var (Normal "a")]))
  144. ]
  145. testWith FSharpTypes.debinarize tests
  146. [<Test>]
  147. member this.TestIsArray() =
  148. let gca = rawts |> Seq.find (fun m -> m.DisplayName = "GetCustomAttributes")
  149. Assert.IsFalse (FSharpTypes.isArray (gca.Type.GenericArguments.[0]))
  150. Assert.IsTrue (FSharpTypes.isArray (gca.Type.GenericArguments.[1].GenericArguments.[1]))
  151. [<Test>]
  152. member this.TestDimensions() =
  153. let gca = rawts |> Seq.find (fun m -> m.DisplayName = "GetCustomAttributes")
  154. let ara = gca.Type.GenericArguments.[1].GenericArguments.[1]
  155. Assert.AreEqual ("[]", ara.NamedEntity.DisplayName)
  156. Assert.AreEqual (1,FSharpTypes.dimensions gca.Type.GenericArguments.[1].GenericArguments.[1])
  157. [<Test>]
  158. member this.TestCvt() =
  159. for t in rawts do
  160. if t.Type.IsFunction then
  161. Assert.IsTrue (match FSharpTypes.cvt t.Type with
  162. | Arrow _ -> true
  163. | _ -> false)
  164. elif t.Type.IsTuple then
  165. Assert.IsTrue (match FSharpTypes.cvt t.Type with
  166. | Tuple _ -> true
  167. | _ -> false)
  168. let getT name = rawts |> Seq.find (fun t -> t.DisplayName = name)
  169. let t1 = getT "GetCustomAttributes"
  170. let t2 = getT "GetExceptionFields"
  171. let t3 = getT "Cast"
  172. let intmod (t : FSharpMemberOrVal) = t.DisplayName = "( % )"
  173. && not t.Type.GenericArguments.[0].IsTuple
  174. let t4 = rawts |> Seq.find intmod
  175. Assert.AreEqual(1, rawts |> Seq.filter intmod |> Seq.length)
  176. // TODO: test int defaulting
  177. // and someday whenify and canonicalType when those features are to be completed
  178. Assert.IsTrue (match FSharpTypes.cvt t1.Type with
  179. | Arrow _ -> true
  180. | _ -> false)
  181. Assert.AreEqual(FSharpTypes.cvt t1.Type.GenericArguments.[0], Id "UnionCaseInfo")
  182. Assert.AreEqual(FSharpTypes.cvt t1.Type.GenericArguments.[1].GenericArguments.[1],
  183. Array (1, Id "Object"))
  184. Assert.IsTrue (match FSharpTypes.cvt t2.Type.GenericArguments.[0] with
  185. | Tuple _ -> true
  186. | _ -> false)
  187. Assert.AreEqual(FSharpTypes.cvt t2.Type.GenericArguments.[0].GenericArguments.[1],
  188. Generic (Id "Option", [Id "BindingFlags"]))
  189. Assert.AreEqual(FSharpTypes.cvt t3.Type.GenericArguments.[1],
  190. Generic (Id "Expr", [Var (Normal "T")]))
  191. Assert.AreEqual(FSharpTypes.cvt t4.Type.GenericArguments.[0],
  192. Id "Int32")