1+ module FSharp.Compiler.UnitTests.FsiTests
2+
3+ open System.IO
4+ open FSharp.Compiler .Interactive .Shell
5+ open NUnit.Framework
6+
7+ let createFsiSession () =
8+ // Intialize output and input streams
9+ let inStream = new StringReader( " " )
10+ let outStream = new CompilerOutputStream()
11+ let errStream = new CompilerOutputStream()
12+
13+ // Build command line arguments & start FSI session
14+ let argv = [| " C:\\ fsi.exe" |]
15+ let allArgs = Array.append argv [| " --noninteractive" |]
16+
17+ let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
18+ FsiEvaluationSession.Create( fsiConfig, allArgs, inStream, new StreamWriter( outStream), new StreamWriter( errStream), collectible = true )
19+
20+ [<Test>]
21+ let ``No bound values at the start of FSI session`` () =
22+ use fsiSession = createFsiSession ()
23+ let values = fsiSession.GetBoundValues()
24+ Assert.IsEmpty values
25+
26+ [<Test>]
27+ let ``Bound value has correct name`` () =
28+ use fsiSession = createFsiSession ()
29+
30+ fsiSession.EvalInteraction( " let x = 1" )
31+
32+ let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne
33+
34+ Assert.AreEqual( " x" , boundValue.Name)
35+
36+ [<Test>]
37+ let ``Bound value has correct value`` () =
38+ use fsiSession = createFsiSession ()
39+
40+ fsiSession.EvalInteraction( " let y = 2" )
41+
42+ let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne
43+
44+ Assert.AreEqual( 2 , boundValue.Value.ReflectionValue)
45+
46+ [<Test>]
47+ let ``Bound value has correct type`` () =
48+ use fsiSession = createFsiSession ()
49+
50+ fsiSession.EvalInteraction( " let z = 3" )
51+
52+ let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne
53+
54+ Assert.AreEqual( typeof< int>, boundValue.Value.ReflectionType)
55+
56+ [<Test>]
57+ let ``Seven bound values are ordered and have their correct name`` () =
58+ use fsiSession = createFsiSession ()
59+
60+ fsiSession.EvalInteraction( " let x = 1" )
61+ fsiSession.EvalInteraction( " let y = 2" )
62+ fsiSession.EvalInteraction( " let z = 3" )
63+ fsiSession.EvalInteraction( " let a = 4" )
64+ fsiSession.EvalInteraction( " let ccc = 5" )
65+ fsiSession.EvalInteraction( " let b = 6" )
66+ fsiSession.EvalInteraction( " let aa = 7" )
67+
68+ let names = fsiSession.GetBoundValues() |> List.map ( fun x -> x.Name)
69+
70+ Assert.AreEqual([ " a" ; " aa" ; " b" ; " ccc" ; " x" ; " y" ; " z" ], names)
71+
72+ [<Test>]
73+ let ``Seven bound values are ordered and have their correct value`` () =
74+ use fsiSession = createFsiSession ()
75+
76+ fsiSession.EvalInteraction( " let x = 1" )
77+ fsiSession.EvalInteraction( " let y = 2" )
78+ fsiSession.EvalInteraction( " let z = 3" )
79+ fsiSession.EvalInteraction( " let a = 4" )
80+ fsiSession.EvalInteraction( " let ccc = 5" )
81+ fsiSession.EvalInteraction( " let b = 6" )
82+ fsiSession.EvalInteraction( " let aa = 7" )
83+
84+ let values = fsiSession.GetBoundValues() |> List.map ( fun x -> x.Value.ReflectionValue)
85+
86+ Assert.AreEqual([ 4 ; 7 ; 6 ; 5 ; 1 ; 2 ; 3 ], values)
87+
88+ [<Test>]
89+ let ``Seven bound values are ordered and have their correct type`` () =
90+ use fsiSession = createFsiSession ()
91+
92+ fsiSession.EvalInteraction( " let x = 1" )
93+ fsiSession.EvalInteraction( " let y = 2" )
94+ fsiSession.EvalInteraction( " let z = 3" )
95+ fsiSession.EvalInteraction( " let a = 4." )
96+ fsiSession.EvalInteraction( " let ccc = 5" )
97+ fsiSession.EvalInteraction( " let b = 6.f" )
98+ fsiSession.EvalInteraction( " let aa = 7" )
99+
100+ let types = fsiSession.GetBoundValues() |> List.map ( fun x -> x.Value.ReflectionType)
101+
102+ Assert.AreEqual([ typeof< float>; typeof< int>; typeof< float32>; typeof< int>; typeof< int>; typeof< int>; typeof< int>], types)
103+
104+ [<Test>]
105+ let ``Able to find a bound value by the identifier`` () =
106+ use fsiSession = createFsiSession ()
107+
108+ fsiSession.EvalInteraction( " let x = 1" )
109+ fsiSession.EvalInteraction( " let y = 2" )
110+ fsiSession.EvalInteraction( " let z = 3" )
111+ fsiSession.EvalInteraction( " let a = 4" )
112+ fsiSession.EvalInteraction( " let ccc = 5" )
113+ fsiSession.EvalInteraction( " let b = 6" )
114+ fsiSession.EvalInteraction( " let aa = 7" )
115+
116+ let boundValueOpt = fsiSession.TryFindBoundValue " ccc"
117+
118+ Assert.IsTrue boundValueOpt.IsSome
119+
120+ [<Test>]
121+ let ``Able to find a bound value by the identifier and has valid info`` () =
122+ use fsiSession = createFsiSession ()
123+
124+ fsiSession.EvalInteraction( " let x = 1." )
125+ fsiSession.EvalInteraction( " let y = 2." )
126+ fsiSession.EvalInteraction( " let z = 3" )
127+ fsiSession.EvalInteraction( " let a = 4." )
128+ fsiSession.EvalInteraction( " let ccc = 5." )
129+ fsiSession.EvalInteraction( " let b = 6." )
130+ fsiSession.EvalInteraction( " let aa = 7." )
131+
132+ let boundValue = ( fsiSession.TryFindBoundValue " z" ) .Value
133+
134+ Assert.AreEqual( " z" , boundValue.Name)
135+ Assert.AreEqual( 3 , boundValue.Value.ReflectionValue)
136+ Assert.AreEqual( typeof< int>, boundValue.Value.ReflectionType)
137+
138+ [<Test>]
139+ let ``Not Able to find a bound value by the identifier`` () =
140+ use fsiSession = createFsiSession ()
141+
142+ fsiSession.EvalInteraction( " let x = 1" )
143+ fsiSession.EvalInteraction( " let y = 2" )
144+ fsiSession.EvalInteraction( " let z = 3" )
145+ fsiSession.EvalInteraction( " let a = 4" )
146+ fsiSession.EvalInteraction( " let ccc = 5" )
147+ fsiSession.EvalInteraction( " let b = 6" )
148+ fsiSession.EvalInteraction( " let aa = 7" )
149+
150+ let boundValueOpt = fsiSession.TryFindBoundValue " aaa"
151+
152+ Assert.IsTrue boundValueOpt.IsNone
153+
154+ [<Test>]
155+ let ``The 'it' value does not exist at the start of a FSI session`` () =
156+ use fsiSession = createFsiSession ()
157+
158+ let boundValueOpt = fsiSession.TryFindBoundValue " it"
159+
160+ Assert.IsTrue boundValueOpt.IsNone
161+
162+ [<Test>]
163+ let ``The 'it' bound value does exists after a value is not explicitly bound`` () =
164+ use fsiSession = createFsiSession ()
165+
166+ fsiSession.EvalInteraction( " 456" )
167+
168+ let boundValueOpt = fsiSession.TryFindBoundValue " it"
169+
170+ Assert.IsTrue boundValueOpt.IsSome
171+
172+ [<Test>]
173+ let ``The 'it' value does exists after a value is not explicitly bound and has valid info`` () =
174+ use fsiSession = createFsiSession ()
175+
176+ fsiSession.EvalInteraction( " 456" )
177+
178+ let boundValue = ( fsiSession.TryFindBoundValue " it" ) .Value
179+
180+ Assert.AreEqual( " it" , boundValue.Name)
181+ Assert.AreEqual( 456 , boundValue.Value.ReflectionValue)
182+ Assert.AreEqual( typeof< int>, boundValue.Value.ReflectionType)
183+
184+ [<Test>]
185+ let ``The latest shadowed value is only available`` () =
186+ use fsiSession = createFsiSession ()
187+
188+ fsiSession.EvalInteraction( " let x = 1" )
189+ let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne
190+
191+ Assert.AreEqual( " x" , boundValue.Name)
192+ Assert.AreEqual( 1 , boundValue.Value.ReflectionValue)
193+ Assert.AreEqual( typeof< int>, boundValue.Value.ReflectionType)
194+
195+ fsiSession.EvalInteraction( " let x = (1, 2)" )
196+ let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne
197+
198+ Assert.AreEqual( " x" , boundValue.Name)
199+ Assert.AreEqual(( 1 , 2 ), boundValue.Value.ReflectionValue)
200+ Assert.AreEqual( typeof< int * int>, boundValue.Value.ReflectionType)
201+
202+ [<Test>]
203+ let ``The latest shadowed value is only available and can be found`` () =
204+ use fsiSession = createFsiSession ()
205+
206+ fsiSession.EvalInteraction( " let x = 1" )
207+ let boundValue = ( fsiSession.TryFindBoundValue " x" ) .Value
208+
209+ Assert.AreEqual( " x" , boundValue.Name)
210+ Assert.AreEqual( 1 , boundValue.Value.ReflectionValue)
211+ Assert.AreEqual( typeof< int>, boundValue.Value.ReflectionType)
212+
213+ fsiSession.EvalInteraction( " let x = (1, 2)" )
214+ let boundValue = ( fsiSession.TryFindBoundValue " x" ) .Value
215+
216+ Assert.AreEqual( " x" , boundValue.Name)
217+ Assert.AreEqual(( 1 , 2 ), boundValue.Value.ReflectionValue)
218+ Assert.AreEqual( typeof< int * int>, boundValue.Value.ReflectionType)
219+
220+ [<Test>]
221+ let ``Values are successfully shadowed even with intermediate interactions`` () =
222+ use fsiSession = createFsiSession ()
223+
224+ fsiSession.EvalInteraction( " let x = 1" )
225+ fsiSession.EvalInteraction( " let z = 100" )
226+ fsiSession.EvalInteraction( " let x = (1, 2)" )
227+ fsiSession.EvalInteraction( " let w = obj ()" )
228+
229+ let boundValues = fsiSession.GetBoundValues()
230+
231+ Assert.AreEqual( 3 , boundValues.Length)
232+
233+ let boundValue = boundValues |> List.find ( fun x -> x.Name = " x" )
234+
235+ Assert.AreEqual( " x" , boundValue.Name)
236+ Assert.AreEqual(( 1 , 2 ), boundValue.Value.ReflectionValue)
237+ Assert.AreEqual( typeof< int * int>, boundValue.Value.ReflectionType)
238+
239+ let boundValue = ( fsiSession.TryFindBoundValue " x" ) .Value
240+
241+ Assert.AreEqual( " x" , boundValue.Name)
242+ Assert.AreEqual(( 1 , 2 ), boundValue.Value.ReflectionValue)
243+ Assert.AreEqual( typeof< int * int>, boundValue.Value.ReflectionType)
0 commit comments