PageRenderTime 11ms CodeModel.GetById 1ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs

https://gitlab.com/N3X15/ILSpy
C# | 337 lines | 298 code | 22 blank | 17 comment | 0 complexity | 4a0447c1188684bae632389844ddb9d7 MD5 | raw file
  1// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
  2// 
  3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4// software and associated documentation files (the "Software"), to deal in the Software
  5// without restriction, including without limitation the rights to use, copy, modify, merge,
  6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7// to whom the Software is furnished to do so, subject to the following conditions:
  8// 
  9// The above copyright notice and this permission notice shall be included in all copies or
 10// substantial portions of the Software.
 11// 
 12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 17// DEALINGS IN THE SOFTWARE.
 18
 19using System;
 20using ICSharpCode.NRefactory.Semantics;
 21using ICSharpCode.NRefactory.TypeSystem;
 22using NUnit.Framework;
 23
 24namespace ICSharpCode.NRefactory.CSharp.Resolver
 25{
 26	[TestFixture]
 27	public class LinqTests : ResolverTestBase
 28	{
 29		[Test]
 30		public void SimpleLinq()
 31		{
 32			string program = @"using System; using System.Linq;
 33class TestClass {
 34	void Test(string[] input) {
 35		var r = from e in input
 36			where e.StartsWith(""/"")
 37			select e.Trim();
 38		r.ToString();
 39	}
 40}
 41";
 42			LocalResolveResult lrr = Resolve<LocalResolveResult>(program.Replace("where e", "where $e$"));
 43			Assert.AreEqual("System.String", lrr.Type.ReflectionName);
 44			lrr = Resolve<LocalResolveResult>(program.Replace("select e", "select $e$"));
 45			Assert.AreEqual("System.String", lrr.Type.ReflectionName);
 46			lrr = Resolve<LocalResolveResult>(program.Replace("from e", "from $e$"));
 47			Assert.AreEqual("System.String", lrr.Type.ReflectionName);
 48			
 49			lrr = Resolve<LocalResolveResult>(program.Replace("r.ToString", "$r$.ToString"));
 50			Assert.AreEqual("System.Collections.Generic.IEnumerable", lrr.Type.FullName);
 51			Assert.AreEqual("System.String", ((ParameterizedType)lrr.Type).TypeArguments[0].FullName);
 52		}
 53		
 54		[Test]
 55		public void Group()
 56		{
 57			string program = @"using System; using System.Linq;
 58class TestClass {
 59	void Test(string[] input) {
 60		var r = from e in input
 61			group e.ToUpper() by e.Length;
 62		$r$.ToString();
 63	}
 64}
 65";
 66			LocalResolveResult lrr = Resolve<LocalResolveResult>(program);
 67			Assert.AreEqual("System.Collections.Generic.IEnumerable", lrr.Type.FullName);
 68			ParameterizedType rt = (ParameterizedType)((ParameterizedType)lrr.Type).TypeArguments[0];
 69			Assert.AreEqual("System.Linq.IGrouping", rt.FullName);
 70			Assert.AreEqual("System.Int32", rt.TypeArguments[0].FullName);
 71			Assert.AreEqual("System.String", rt.TypeArguments[1].FullName);
 72		}
 73		
 74		[Test]
 75		public void QueryableGroup()
 76		{
 77			string program = @"using System; using System.Linq;
 78class TestClass {
 79	void Test(IQueryable<string> input) {
 80		var r = from e in input
 81			group e.ToUpper() by e.Length;
 82		$r$.ToString();
 83	}
 84}
 85";
 86			LocalResolveResult lrr = Resolve<LocalResolveResult>(program);
 87			Assert.AreEqual("System.Linq.IQueryable", lrr.Type.FullName);
 88			ParameterizedType rt = (ParameterizedType)((ParameterizedType)lrr.Type).TypeArguments[0];
 89			Assert.AreEqual("System.Linq.IGrouping", rt.FullName);
 90			Assert.AreEqual("System.Int32", rt.TypeArguments[0].FullName);
 91			Assert.AreEqual("System.String", rt.TypeArguments[1].FullName);
 92		}
 93		
 94		[Test]
 95		public void Parenthesized()
 96		{
 97			string program = @"using System; using System.Linq;
 98class TestClass {
 99	void Test(string[] input) {
100		$(from e in input select e.Length)$.ToArray();
101	}
102}
103";
104			var rr = Resolve<CSharpInvocationResolveResult>(program);
105			Assert.AreEqual("System.Linq.Enumerable.Select", rr.Member.FullName);
106			Assert.AreEqual("System.Collections.Generic.IEnumerable", rr.Type.FullName);
107			Assert.AreEqual("System.Int32", ((ParameterizedType)rr.Type).TypeArguments[0].FullName);
108		}
109		
110		[Test]
111		public void SelectReturnType()
112		{
113			string program = @"using System;
114class TestClass { static void M() {
115	$(from a in new XYZ() select a.ToUpper())$.ToString();
116}}
117class XYZ {
118	public int Select<U>(Func<string, U> f) { return 42; }
119}";
120			var rr = Resolve<CSharpInvocationResolveResult>(program);
121			Assert.AreEqual("XYZ.Select", rr.Member.FullName);
122			Assert.AreEqual("System.Int32", rr.Type.FullName);
123		}
124		
125		[Test]
126		public void Continuation()
127		{
128			string program = @"using System; using System.Linq;
129class TestClass {
130	void Test(string[] input) {
131		var r = from x in input
132			select x.GetHashCode() into x
133			where x == 42
134			select x * x;
135		r.ToString();
136	}
137}
138";
139			LocalResolveResult lrr = Resolve<LocalResolveResult>(program.Replace("from x", "from $x$"));
140			Assert.AreEqual("System.String", lrr.Type.ReflectionName);
141			lrr = Resolve<LocalResolveResult>(program.Replace("select x.G", "select $x$.G"));
142			Assert.AreEqual("System.String", lrr.Type.ReflectionName);
143			lrr = Resolve<LocalResolveResult>(program.Replace("into x", "into $x$"));
144			Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
145			lrr = Resolve<LocalResolveResult>(program.Replace("where x", "where $x$"));
146			Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
147			lrr = Resolve<LocalResolveResult>(program.Replace("select x * x", "select x * $x$"));
148			Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
149			
150			lrr = Resolve<LocalResolveResult>(program.Replace("r.ToString", "$r$.ToString"));
151			Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.Int32]]", lrr.Type.ReflectionName);
152		}
153		
154		[Test]
155		public void OrderingWithSelectCall()
156		{
157			string program = @"using System; using System.Linq;
158class TestClass {
159	void Test(string[] input) {
160		$var$ r = from x in input
161			orderby x.Length
162			select x + x;
163	}
164}
165";
166			TypeResolveResult rr = Resolve<TypeResolveResult>(program);
167			Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
168		}
169		
170		[Test]
171		public void OrderingWithoutSelectCall()
172		{
173			string program = @"using System; using System.Linq;
174class TestClass {
175	void Test(string[] input) {
176		$var$ r = from x in input
177			orderby x.Length
178			select x;
179	}
180}
181";
182			TypeResolveResult rr = Resolve<TypeResolveResult>(program);
183			Assert.AreEqual("System.Linq.IOrderedEnumerable`1[[System.String]]", rr.Type.ReflectionName);
184		}
185		
186		[Test]
187		public void OrderingWithSelectCallDueToSecondRangeVariable1()
188		{
189			string program = @"using System; using System.Linq;
190class TestClass {
191	void Test(string[] input) {
192		$var$ r = from x in input
193			from y in input
194			orderby x.Length
195			select x;
196	}
197}
198";
199			TypeResolveResult rr = Resolve<TypeResolveResult>(program);
200			Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
201		}
202		
203		[Test]
204		public void OrderingWithSelectCallDueToSecondRangeVariable2()
205		{
206			string program = @"using System; using System.Linq;
207class TestClass {
208	void Test(string[] input) {
209		$var$ r = from x in input
210			join y in input on x equals y
211			orderby x.Length
212			select x;
213	}
214}
215";
216			TypeResolveResult rr = Resolve<TypeResolveResult>(program);
217			Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
218		}
219		
220		[Test]
221		public void OrderingWithSelectCallDueToSecondRangeVariable3()
222		{
223			string program = @"using System; using System.Linq;
224class TestClass {
225	void Test(string[] input) {
226		$var$ r = from x in input
227			join y in input on x equals y into g
228			orderby x.Length
229			select x;
230	}
231}
232";
233			TypeResolveResult rr = Resolve<TypeResolveResult>(program);
234			Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
235		}
236		
237		[Test]
238		public void OrderingWithSelectCallDueToSecondRangeVariable4()
239		{
240			string program = @"using System; using System.Linq;
241class TestClass {
242	void Test(string[] input) {
243		$var$ r = from x in input
244			let y = x
245			orderby x.Length
246			select x;
247	}
248}
249";
250			TypeResolveResult rr = Resolve<TypeResolveResult>(program);
251			Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
252		}
253		
254		[Test]
255		public void DegenerateQuery()
256		{
257			string program = @"using System; using System.Linq;
258class TestClass {
259	void Test(string[] input) {
260		$var$ r = from x in input select x;
261	}
262}
263";
264			TypeResolveResult rr = Resolve<TypeResolveResult>(program);
265			Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
266		}
267		
268		[Test, Ignore("Parser bug (incorrect position), but also resolver bug (handles Select as a separate call when it's combined into the GroupJoin)")]
269		public void GroupJoinWithCustomMethod()
270		{
271			string program = @"using System;
272using System.Collections.Generic;
273class TestClass { static void M(long [] args) {
274	var q = (from a in new XYZ() join b in args on a equals b into g select g);
275}}
276class XYZ {
277	public XYZ GroupJoin<T, R>(IEnumerable<T> f, Func<string, object> key1, Func<T, object> key2, Func<string, decimal, R> s) { return this; }
278	public int Select<U>(Func<string, U> f) { return 42; }
279}";
280			var local = Resolve<LocalResolveResult>(program.Replace("into g", "into $g$"));
281			Assert.AreEqual("System.Decimal", local.Type.FullName);
282			
283			local = Resolve<LocalResolveResult>(program.Replace("select g", "select $g$"));
284			Assert.AreEqual("System.Decimal", local.Type.FullName);
285			
286			var trr = Resolve<TypeResolveResult>(program.Replace("var", "$var$"));
287			Assert.AreEqual("XYZ", trr.Type.FullName); // because 'Select' is done as part of GroupJoin()
288		}
289		
290		[Test]
291		public void GroupJoinWithOverloadedCustomMethod()
292		{
293			string program = @"using System;
294using System.Collections.Generic;
295class TestClass
296{
297	static void M(string[] args)
298	{
299		var q = $(from a in new XYZ() join b in args on a equals b into g select g.ToUpper())$;
300	}
301}
302class XYZ
303{
304	public int GroupJoin(IEnumerable<string> f, Func<string, object> key1, Func<string, object> key2, Func<string, int, int> s) { return 0; }
305	public decimal GroupJoin(IEnumerable<string> f, Func<string, object> key1, Func<string, object> key2, Func<string, string, string> s) { return 0; }
306}";
307			var rr = Resolve<CSharpInvocationResolveResult>(program);
308			Assert.IsFalse(rr.IsError);
309			Assert.AreEqual("GroupJoin", rr.Member.Name);
310			Assert.AreEqual("System.Decimal", rr.Type.FullName);
311			
312			rr = Resolve<CSharpInvocationResolveResult>(program.Replace("g.ToUpper()", "g.CompareTo(42)"));
313			Assert.IsFalse(rr.IsError);
314			Assert.AreEqual("GroupJoin", rr.Member.Name);
315			Assert.AreEqual("System.Int32", rr.Type.FullName);
316		}
317		
318		[Test]
319		public void GroupWithQueryContinuation()
320		{
321			string program = @"using System; using System.Linq;
322class TestClass
323{
324	static void M(string[] args)
325	{
326		var query =
327		from w in ""one to three"".Split()
328			group w by w.Length into g
329			orderby g.Key descending
330			select new { g.Key, Count = g.Count(), Avg = g.Average ($w$ => w.Length) };
331	}
332}";
333			var rr = Resolve<LocalResolveResult>(program);
334			Assert.AreEqual("System.String", rr.Type.FullName);
335		}
336	}
337}