Skip to content

Commit cf7bed8

Browse files
authored
21.2.2 mvvm light support (#12)
* Add_MvvmLight_Support * Add mvvm light tests + fix relayCommand namespace * remove KeepTargetAlive command property + refactoring * Refactoring * fix format
1 parent 9f60091 commit cf7bed8

34 files changed

+1600
-159
lines changed

DevExpress.Mvvm.CodeGenerators.Tests/FrameworkTests/FrameworkTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
</ItemGroup>
4949
<ItemGroup>
5050
<PackageReference Include="DevExpressMvvm" Version="20.2.3" />
51+
<PackageReference Include="MvvmLightLibsStd10" Version="5.4.1.1" />
5152
<PackageReference Include="Prism.Wpf" Version="8.1.97" />
5253
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" />
5354
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" />

DevExpress.Mvvm.CodeGenerators.Tests/NetCoreTests/NetCoreTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
<ItemGroup>
1818
<PackageReference Include="DevExpressMvvm" Version="20.2.3" />
19+
<PackageReference Include="MvvmLightLibsStd10" Version="5.4.1.1" />
1920
<PackageReference Include="Prism.Wpf" Version="8.1.97" />
2021
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" />
2122
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" />
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Reflection;
4+
using System.Threading.Tasks;
5+
using DevExpress.Mvvm.CodeGenerators.MvvmLight;
6+
using GalaSoft.MvvmLight.Helpers;
7+
#if NETCOREAPP
8+
using GalaSoft.MvvmLight.Command;
9+
#else
10+
using GalaSoft.MvvmLight.CommandWpf;
11+
#endif
12+
namespace MvvmLight.Mvvm.Tests {
13+
[GenerateViewModel]
14+
partial class GenerateAsyncCommands {
15+
readonly Task<int> task = new(() => 1);
16+
[GenerateCommand]
17+
public Task WithNoArg() => Task.CompletedTask;
18+
[GenerateCommand]
19+
public Task WithArg(int arg) => Task.CompletedTask;
20+
[GenerateCommand]
21+
public Task WithNullableArg(int? arg) => Task.CompletedTask;
22+
public Task SomeMethod() => Task.CompletedTask;
23+
24+
[GenerateCommand(Name = "MyAsyncCommand", CanExecuteMethod = "CanDoIt")]
25+
public Task Method(int arg) => Task.CompletedTask;
26+
public bool CanDoIt(int arg) => arg > 0;
27+
28+
[GenerateCommand]
29+
public Task<int> GenericTask() => task;
30+
}
31+
32+
[TestFixture]
33+
public class AsyncCommandGenerationTests {
34+
[Test]
35+
public void CallRequiredMethodForAsyncCommand() {
36+
var generated = new GenerateAsyncCommands();
37+
38+
var method = GetFieldValue<WeakAction<int>, RelayCommand<int>>(generated.MyAsyncCommand, "_execute");
39+
StringAssert.Contains("MyAsyncCommand", method.MethodName);
40+
41+
var canMethod = GetFieldValue<WeakFunc<int, bool>, RelayCommand<int>>(generated.MyAsyncCommand, "_canExecute");
42+
var expectedCanMethod = generated.GetType().GetMethod("CanDoIt").Name;
43+
Assert.AreEqual(expectedCanMethod, canMethod.MethodName);
44+
45+
var canExecuteMethod = GetFieldValue<WeakFunc<int, bool>, RelayCommand>(generated.GenericTaskCommand, "_canExecute");
46+
Assert.IsNull(canExecuteMethod);
47+
}
48+
49+
static TResult GetFieldValue<TResult, T>(T source, string fieldName) {
50+
var fieldInfo = source.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
51+
Assert.IsNotNull(fieldInfo);
52+
53+
return (TResult)fieldInfo.GetValue(source);
54+
}
55+
[Test]
56+
public void AsyncCommandImplementation() {
57+
var generated = new GenerateAsyncCommands();
58+
59+
Assert.IsNotNull(generated.GetType().GetProperty("WithNoArgCommand"));
60+
Assert.IsNotNull(generated.GetType().GetProperty("WithArgCommand"));
61+
Assert.IsNotNull(generated.GetType().GetProperty("WithNullableArgCommand"));
62+
63+
Assert.IsNull(generated.GetType().GetProperty("With2ArgsCommand"));
64+
Assert.IsNull(generated.GetType().GetProperty("ReturnNoTaskCommand"));
65+
Assert.IsNull(generated.GetType().GetProperty("SomeMethodCommand"));
66+
}
67+
68+
[Test]
69+
public void ArgumentTypeForAsyncCommand() {
70+
var generated = new GenerateAsyncCommands();
71+
72+
var noArgumentType = generated.WithNoArgCommand.GetType();
73+
Assert.IsEmpty(noArgumentType.GetGenericArguments());
74+
var expectedType = typeof(RelayCommand);
75+
Assert.AreEqual(expectedType, noArgumentType);
76+
77+
var intArgumentType = generated.WithArgCommand.GetType().GetGenericArguments()[0];
78+
var intExpectedType = typeof(int);
79+
Assert.AreEqual(intExpectedType, intArgumentType);
80+
81+
var nullableIntArgumentType = generated.WithNullableArgCommand.GetType().GetGenericArguments()[0];
82+
var nullableIntExpectedType = typeof(int?);
83+
Assert.AreEqual(nullableIntExpectedType, nullableIntArgumentType);
84+
}
85+
}
86+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using DevExpress.Mvvm.CodeGenerators.Tests.Included;
2+
using NUnit.Framework;
3+
using System;
4+
using System.ComponentModel;
5+
using System.ComponentModel.DataAnnotations;
6+
using DevExpress.Mvvm.CodeGenerators.MvvmLight;
7+
8+
namespace MvvmLight.Mvvm.Tests {
9+
class MyCustomAttribute : Attribute {
10+
public MyCustomAttribute(int value, string str, bool condition, TestEnum testEnum) { }
11+
}
12+
namespace Included {
13+
enum TestEnum {
14+
Num = 1,
15+
String = 2
16+
}
17+
}
18+
[GenerateViewModel]
19+
partial class AttributeTransfer {
20+
const int number = 1;
21+
22+
[GenerateProperty]
23+
int noAttribute;
24+
25+
[GenerateProperty, System.ComponentModel.DataAnnotations.Range(0, 1)]
26+
[Required, MyCustom(number,
27+
"Some string",
28+
true, TestEnum.Num)]
29+
int withMultipleAttributes;
30+
}
31+
32+
[TestFixture]
33+
public class AttributeTransferTests {
34+
[Test]
35+
public void AttributeTransfer() {
36+
var noAttributeProperty = typeof(AttributeTransfer).GetProperty("NoAttribute");
37+
var attributes = Attribute.GetCustomAttributes(noAttributeProperty);
38+
var expectedAttributes = new Attribute[] { };
39+
Assert.AreEqual(expectedAttributes, attributes);
40+
41+
var withMultipleAttributesProperty = typeof(AttributeTransfer).GetProperty("WithMultipleAttributes");
42+
attributes = Attribute.GetCustomAttributes(withMultipleAttributesProperty);
43+
expectedAttributes = new Attribute[] {
44+
new System.ComponentModel.DataAnnotations.RangeAttribute(0, 1),
45+
new RequiredAttribute(),
46+
new MyCustomAttribute(1, "Some string", true, TestEnum.Num)
47+
};
48+
Assert.AreEqual(expectedAttributes, attributes);
49+
}
50+
}
51+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Reflection;
4+
using DevExpress.Mvvm.CodeGenerators.MvvmLight;
5+
using GalaSoft.MvvmLight.Helpers;
6+
#if NETCOREAPP
7+
using GalaSoft.MvvmLight.Command;
8+
#else
9+
using GalaSoft.MvvmLight.CommandWpf;
10+
#endif
11+
12+
namespace MvvmLight.Mvvm.Tests {
13+
[GenerateViewModel]
14+
partial class GenerateCommands {
15+
[GenerateCommand]
16+
public void WithNoArg() { }
17+
[GenerateCommand]
18+
public void WithArg(int arg) { }
19+
[GenerateCommand]
20+
public void WithNullableArg(int? arg) { }
21+
public void SomeMethod() { }
22+
public void With2Args(int a, string str) { }
23+
24+
[GenerateCommand(Name = "Command", CanExecuteMethod = "CanDoIt")]
25+
public void Method(int arg) { }
26+
public bool CanDoIt(int arg) => arg > 0;
27+
28+
#nullable enable
29+
[GenerateCommand]
30+
void WithNullableString1(string? str) { }
31+
[GenerateCommand]
32+
void WithNullableString2(string str) { }
33+
[GenerateCommand]
34+
void WithNullableString3(string? str) { }
35+
bool CanWithNullableString3(string str) => str.Length > 0;
36+
bool CanWithNullableString4(string? str) => str?.Length > 0;
37+
#nullable disable
38+
[GenerateCommand]
39+
void WithNullableString4(string str) { }
40+
bool CanWithNullableString1(string str) => str?.Length > 0;
41+
bool CanWithNullableString2(string str) => str.Length > 0;
42+
}
43+
44+
[TestFixture]
45+
public class CommandGenerationTests {
46+
[Test]
47+
public void CommandImplementation() {
48+
var generated = new GenerateCommands();
49+
50+
Assert.IsNotNull(generated.GetType().GetProperty("WithNoArgCommand"));
51+
Assert.IsNotNull(generated.GetType().GetProperty("WithArgCommand"));
52+
Assert.IsNotNull(generated.GetType().GetProperty("WithNullableArgCommand"));
53+
54+
Assert.IsNull(generated.GetType().GetProperty("With2ArgsCommand"));
55+
Assert.IsNull(generated.GetType().GetProperty("ReturnNoVoidCommand"));
56+
Assert.IsNull(generated.GetType().GetProperty("SomeMethodCommand"));
57+
}
58+
59+
[Test]
60+
public void CallRequiredMethodForCommand() {
61+
var generated = new GenerateCommands();
62+
63+
var expectedExecuteMethodWithNoArg = generated.GetType().GetMethod("WithNullableArg");
64+
var executeMethodWithNoArg = GetFieldValueMethod<MethodInfo, RelayCommand<int?>, WeakAction<int?>>(generated.WithNullableArgCommand, "_execute");
65+
Assert.AreEqual(expectedExecuteMethodWithNoArg, executeMethodWithNoArg);
66+
67+
var method = GetFieldValueMethod<MethodInfo, RelayCommand<int>, WeakAction<int>>(generated.Command, "_execute");
68+
var expectedMethod = generated.GetType().GetMethod("Method");
69+
Assert.AreEqual(expectedMethod, method);
70+
71+
var canMethod = GetFieldValueMethod<MethodInfo, RelayCommand<int>, WeakFunc<bool>>(generated.Command, "_canExecute");
72+
var expectedCanMethod = generated.GetType().GetMethod("CanDoIt");
73+
Assert.AreEqual(expectedCanMethod, canMethod);
74+
}
75+
static TResult GetFieldValueMethod<TResult, TCommand, T>(TCommand source, string fieldName) {
76+
var fieldInfo = source.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
77+
Assert.IsNotNull(fieldInfo);
78+
var fieldInsance = fieldInfo.GetValue(source);
79+
var weakMethod = typeof(T).GetProperty("Method", BindingFlags.NonPublic | BindingFlags.Instance);
80+
return (TResult)weakMethod.GetValue(fieldInsance);
81+
}
82+
[Test]
83+
public void ArgumentTypeForCommand() {
84+
var generated = new GenerateCommands();
85+
86+
var noArgumentType = generated.WithNoArgCommand.GetType();
87+
Assert.IsEmpty(noArgumentType.GetGenericArguments());
88+
var expectedType = typeof(RelayCommand);
89+
Assert.AreEqual(expectedType, noArgumentType);
90+
91+
var intArgumentType = generated.WithArgCommand.GetType().GetGenericArguments()[0];
92+
var intExpectedType = typeof(int);
93+
Assert.AreEqual(intExpectedType, intArgumentType);
94+
95+
var nullableIntArgumentType = generated.WithNullableArgCommand.GetType().GetGenericArguments()[0];
96+
var nullableIntExpectedType = typeof(int?);
97+
Assert.AreEqual(nullableIntExpectedType, nullableIntArgumentType);
98+
}
99+
100+
[Test]
101+
public void NullableReferenceType() {
102+
var generated = new GenerateCommands();
103+
104+
Assert.IsTrue(generated.WithNullableString1Command.CanExecute("1"));
105+
Assert.IsTrue(generated.WithNullableString2Command.CanExecute("1"));
106+
Assert.IsTrue(generated.WithNullableString3Command.CanExecute("1"));
107+
Assert.IsTrue(generated.WithNullableString4Command.CanExecute("1"));
108+
109+
Assert.IsFalse(generated.WithNullableString1Command.CanExecute(null));
110+
Assert.IsFalse(generated.WithNullableString2Command.CanExecute(""));
111+
Assert.IsTrue(generated.WithNullableString3Command.CanExecute(""));
112+
Assert.IsFalse(generated.WithNullableString4Command.CanExecute(null));
113+
}
114+
}
115+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using Microsoft.CodeAnalysis;
2+
using Microsoft.CodeAnalysis.CSharp;
3+
using NUnit.Framework;
4+
using System;
5+
using System.ComponentModel;
6+
using DevExpress.Mvvm.CodeGenerators.MvvmLight;
7+
8+
namespace MvvmLight.Mvvm.Tests {
9+
static class DoWith {
10+
static void EventCore<TSender, THandler, TArgs>(
11+
TSender sender,
12+
Action action,
13+
Action<TArgs> eventAction,
14+
Func<TSender, EventHandler<TArgs>, THandler> subscribe,
15+
Action<TSender, THandler> unsubscribe,
16+
int expectedFireCount = 1)
17+
where TArgs : EventArgs {
18+
19+
var fireCount = 0;
20+
EventHandler<TArgs> handler = (o, e) => {
21+
Assert.AreSame(o, sender);
22+
eventAction(e);
23+
fireCount++;
24+
};
25+
26+
var h = subscribe(sender, handler);
27+
try {
28+
action();
29+
} finally {
30+
unsubscribe(sender, h);
31+
}
32+
Assert.AreEqual(expectedFireCount, fireCount);
33+
}
34+
35+
public static void PropertyChangedEvent(INotifyPropertyChanged inpc, Action action, Action<PropertyChangedEventArgs> eventAction, int fireCount = 1) {
36+
EventCore(
37+
inpc,
38+
action,
39+
eventAction,
40+
(o, handler) => {
41+
PropertyChangedEventHandler x = (sender, args) => handler(sender, args);
42+
inpc.PropertyChanged += x;
43+
return x;
44+
},
45+
(o, handler) => inpc.PropertyChanged -= handler,
46+
fireCount
47+
);
48+
}
49+
public static void PropertyChangingEvent(INotifyPropertyChanging inpc, Action action, Action<PropertyChangingEventArgs> eventAction, int fireCount = 1) {
50+
EventCore(
51+
inpc,
52+
action,
53+
eventAction,
54+
(o, handler) => {
55+
PropertyChangingEventHandler x = (sender, args) => handler(sender, args);
56+
inpc.PropertyChanging += x;
57+
return x;
58+
},
59+
(o, handler) => inpc.PropertyChanging -= handler,
60+
fireCount
61+
);
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)