|
|
@ -2,6 +2,10 @@ |
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
|
|
|
|
|
|
|
|
using System; |
|
|
|
using System; |
|
|
|
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
|
|
|
using System.Collections.Specialized; |
|
|
|
|
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
|
|
|
|
using ICSharpCode.NRefactory.CSharp; |
|
|
|
using ICSharpCode.NRefactory.CSharp; |
|
|
|
using ICSharpCode.NRefactory.TypeSystem; |
|
|
|
using ICSharpCode.NRefactory.TypeSystem; |
|
|
|
using ICSharpCode.SharpDevelop.Parser; |
|
|
|
using ICSharpCode.SharpDevelop.Parser; |
|
|
@ -18,6 +22,7 @@ namespace ICSharpCode.SharpDevelop.Dom |
|
|
|
IProjectContent projectContent; |
|
|
|
IProjectContent projectContent; |
|
|
|
IEntityModelContext context; |
|
|
|
IEntityModelContext context; |
|
|
|
TopLevelTypeDefinitionModelCollection topLevelTypeModels; |
|
|
|
TopLevelTypeDefinitionModelCollection topLevelTypeModels; |
|
|
|
|
|
|
|
List<NotifyCollectionChangedEventArgs> topLevelChangeEventArgs = new List<NotifyCollectionChangedEventArgs>(); |
|
|
|
|
|
|
|
|
|
|
|
#region SetUp and other helper methods
|
|
|
|
#region SetUp and other helper methods
|
|
|
|
[SetUp] |
|
|
|
[SetUp] |
|
|
@ -25,12 +30,16 @@ namespace ICSharpCode.SharpDevelop.Dom |
|
|
|
{ |
|
|
|
{ |
|
|
|
SD.InitializeForUnitTests(); |
|
|
|
SD.InitializeForUnitTests(); |
|
|
|
SD.Services.AddStrictMockService<IParserService>(); |
|
|
|
SD.Services.AddStrictMockService<IParserService>(); |
|
|
|
|
|
|
|
SD.Services.AddStrictMockService<IMessageLoop>(); |
|
|
|
|
|
|
|
SD.MainThread.Stub(m => m.VerifyAccess()); |
|
|
|
project = MockRepository.GenerateStrictMock<IProject>(); |
|
|
|
project = MockRepository.GenerateStrictMock<IProject>(); |
|
|
|
projectContent = new CSharpProjectContent().AddAssemblyReferences(AssemblyLoader.Corlib); |
|
|
|
projectContent = new CSharpProjectContent().AddAssemblyReferences(AssemblyLoader.Corlib); |
|
|
|
context = new ProjectEntityModelContext(project, ".cs"); |
|
|
|
context = new ProjectEntityModelContext(project, ".cs"); |
|
|
|
topLevelTypeModels = new TopLevelTypeDefinitionModelCollection(context); |
|
|
|
topLevelTypeModels = new TopLevelTypeDefinitionModelCollection(context); |
|
|
|
|
|
|
|
|
|
|
|
SD.ParserService.Stub(p => p.GetCompilation(project)).WhenCalled(c => c.ReturnValue = projectContent.CreateCompilation()); |
|
|
|
SD.ParserService.Stub(p => p.GetCompilation(project)).WhenCalled(c => c.ReturnValue = projectContent.CreateCompilation()); |
|
|
|
|
|
|
|
topLevelChangeEventArgs.Clear(); |
|
|
|
|
|
|
|
topLevelTypeModels.CollectionChanged += (sender, e) => topLevelChangeEventArgs.Add(e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[TearDown] |
|
|
|
[TearDown] |
|
|
@ -77,14 +86,140 @@ namespace ICSharpCode.SharpDevelop.Dom |
|
|
|
public void EmptyProject() |
|
|
|
public void EmptyProject() |
|
|
|
{ |
|
|
|
{ |
|
|
|
Assert.AreEqual(0, topLevelTypeModels.Count); |
|
|
|
Assert.AreEqual(0, topLevelTypeModels.Count); |
|
|
|
Assert.IsNull(topLevelTypeModels[new TopLevelTypeName("A")]); |
|
|
|
Assert.IsNull(topLevelTypeModels[new TopLevelTypeName("MissingClass")]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Simple class
|
|
|
|
[Test] |
|
|
|
[Test] |
|
|
|
public void AddSimpleClass() |
|
|
|
public void AddSimpleClass() |
|
|
|
{ |
|
|
|
{ |
|
|
|
AddCodeFile("test.cs", @"class SimpleClass {}"); |
|
|
|
AddCodeFile("test.cs", @"class SimpleClass {}"); |
|
|
|
Assert.AreEqual(1, topLevelTypeModels.Count); |
|
|
|
Assert.AreEqual(1, topLevelTypeModels.Count); |
|
|
|
|
|
|
|
var simpleClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
Assert.AreEqual(NotifyCollectionChangedAction.Add, topLevelChangeEventArgs.Single().Action); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { simpleClass }, topLevelChangeEventArgs.Single().NewItems); |
|
|
|
|
|
|
|
topLevelChangeEventArgs.Clear(); // clear for follow-up tests
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void UpdateSimpleClass() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddSimpleClass(); |
|
|
|
|
|
|
|
var simpleClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
Assert.AreEqual(0, simpleClass.Members.Count); |
|
|
|
|
|
|
|
UpdateCodeFile("test.cs", "class SimpleClass { void Method() {} }"); |
|
|
|
|
|
|
|
Assert.AreSame(simpleClass, topLevelTypeModels.Single()); |
|
|
|
|
|
|
|
Assert.AreEqual(1, simpleClass.Members.Count); |
|
|
|
|
|
|
|
Assert.IsEmpty(topLevelChangeEventArgs); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void ReplaceSimpleClass() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddSimpleClass(); |
|
|
|
|
|
|
|
var simpleClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
UpdateCodeFile("test.cs", "class OtherClass { }"); |
|
|
|
|
|
|
|
var otherClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
Assert.AreNotSame(simpleClass, otherClass); |
|
|
|
|
|
|
|
Assert.AreEqual(NotifyCollectionChangedAction.Replace, topLevelChangeEventArgs.Single().Action); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { simpleClass }, topLevelChangeEventArgs.Single().OldItems); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { otherClass }, topLevelChangeEventArgs.Single().NewItems); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void RemoveSimpleClassCodeFile() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddSimpleClass(); |
|
|
|
|
|
|
|
var simpleClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
RemoveCodeFile("test.cs"); |
|
|
|
|
|
|
|
Assert.IsEmpty(topLevelTypeModels); |
|
|
|
|
|
|
|
// check removal event
|
|
|
|
|
|
|
|
Assert.AreEqual(NotifyCollectionChangedAction.Remove, topLevelChangeEventArgs.Single().Action); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { simpleClass }, topLevelChangeEventArgs.Single().OldItems); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// test that accessing properties of a removed class still works
|
|
|
|
|
|
|
|
Assert.AreEqual(new FullTypeName("SimpleClass"), simpleClass.FullTypeName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region TwoPartsInSingleFile
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void TwoPartsInSingleFile() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddCodeFile("test.cs", @"
|
|
|
|
|
|
|
|
partial class SimpleClass { void Member1() {} } |
|
|
|
|
|
|
|
partial class SimpleClass { void Member2() {} }");
|
|
|
|
|
|
|
|
Assert.AreEqual(1, topLevelTypeModels.Count); |
|
|
|
|
|
|
|
topLevelChangeEventArgs.Clear(); // clear for follow-up tests
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void UpdateTwoPartsInSingleFile() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TwoPartsInSingleFile(); |
|
|
|
|
|
|
|
var simpleClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
UpdateCodeFile("test.cs", @"
|
|
|
|
|
|
|
|
partial class SimpleClass { void Member1b() {} } |
|
|
|
|
|
|
|
partial class SimpleClass { void Member2b() {} }");
|
|
|
|
|
|
|
|
Assert.AreSame(simpleClass, topLevelTypeModels.Single()); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { "Member1b", "Member2b" }, simpleClass.Members.Select(m => m.Name).ToArray()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void RemoveOneOfPartsInSingleFile() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TwoPartsInSingleFile(); |
|
|
|
|
|
|
|
var simpleClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
var member1 = simpleClass.Members.First(); |
|
|
|
|
|
|
|
UpdateCodeFile("test.cs", "class SimpleClass { void Member1() {} }"); |
|
|
|
|
|
|
|
Assert.AreSame(simpleClass, topLevelTypeModels.Single()); |
|
|
|
|
|
|
|
Assert.AreSame(member1, simpleClass.Members.Single()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void RemoveBothPartsInSingleFile() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TwoPartsInSingleFile(); |
|
|
|
|
|
|
|
var simpleClass = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
UpdateCodeFile("test.cs", "class OtherClass {}"); |
|
|
|
|
|
|
|
Assert.AreNotSame(simpleClass, topLevelTypeModels.Single()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region TestRegionIsFromPrimaryPart
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void AddingDesignerPartDoesNotChangeRegion() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddCodeFile("Form.cs", "partial class MyForm {}"); |
|
|
|
|
|
|
|
Assert.AreEqual("Form.cs", topLevelTypeModels.Single().Region.FileName); |
|
|
|
|
|
|
|
AddCodeFile("Form.Designer.cs", "partial class MyForm {}"); |
|
|
|
|
|
|
|
Assert.AreEqual("Form.cs", topLevelTypeModels.Single().Region.FileName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void AddingPrimaryPartChangesRegion() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddCodeFile("Form.Designer.cs", "partial class MyForm {}"); |
|
|
|
|
|
|
|
Assert.AreEqual("Form.Designer.cs", topLevelTypeModels.Single().Region.FileName); |
|
|
|
|
|
|
|
AddCodeFile("Form.cs", "partial class MyForm {}"); |
|
|
|
|
|
|
|
Assert.AreEqual("Form.cs", topLevelTypeModels.Single().Region.FileName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
|
|
|
public void RemovingPrimaryPartChangesRegionToNextBestPart() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddCodeFile("Form.cs", "partial class MyForm { int primaryMember; }"); |
|
|
|
|
|
|
|
AddCodeFile("Form.Designer.Designer.cs", "partial class MyForm { int designer2; }"); |
|
|
|
|
|
|
|
var form = topLevelTypeModels.Single(); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { "primaryMember", "designer2" }, form.Members.Select(m => m.Name).ToArray()); |
|
|
|
|
|
|
|
AddCodeFile("Form.Designer.cs", "partial class MyForm { int designer; }"); |
|
|
|
|
|
|
|
Assert.AreEqual("Form.cs", form.Region.FileName); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { "primaryMember", "designer", "designer2" }, form.Members.Select(m => m.Name).ToArray()); |
|
|
|
|
|
|
|
RemoveCodeFile("Form.cs"); |
|
|
|
|
|
|
|
Assert.AreSame(form, topLevelTypeModels.Single()); |
|
|
|
|
|
|
|
Assert.AreEqual("Form.Designer.cs", form.Region.FileName); |
|
|
|
|
|
|
|
Assert.AreEqual(new[] { "designer", "designer2" }, form.Members.Select(m => m.Name).ToArray()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|